xref: /aosp_15_r20/external/cronet/base/debug/stack_trace.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_DEBUG_STACK_TRACE_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_DEBUG_STACK_TRACE_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <iosfwd>
11*6777b538SAndroid Build Coastguard Worker #include <string>
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/debug/debugging_buildflags.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/strings/cstring_view.h"
18*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX)
21*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_NACL)
22*6777b538SAndroid Build Coastguard Worker #include <signal.h>
23*6777b538SAndroid Build Coastguard Worker #endif
24*6777b538SAndroid Build Coastguard Worker #include <unistd.h>
25*6777b538SAndroid Build Coastguard Worker #endif
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
28*6777b538SAndroid Build Coastguard Worker struct _EXCEPTION_POINTERS;
29*6777b538SAndroid Build Coastguard Worker struct _CONTEXT;
30*6777b538SAndroid Build Coastguard Worker #endif
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker namespace base {
33*6777b538SAndroid Build Coastguard Worker namespace debug {
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker // Enables stack dump to console output on exception and signals.
36*6777b538SAndroid Build Coastguard Worker // When enabled, the process will quit immediately. This is meant to be used in
37*6777b538SAndroid Build Coastguard Worker // unit_tests only! This is not thread-safe: only call from main thread.
38*6777b538SAndroid Build Coastguard Worker // In sandboxed processes, this has to be called before the sandbox is turned
39*6777b538SAndroid Build Coastguard Worker // on.
40*6777b538SAndroid Build Coastguard Worker // Calling this function on Linux opens /proc/self/maps and caches its
41*6777b538SAndroid Build Coastguard Worker // contents. In non-official builds, this function also opens the object files
42*6777b538SAndroid Build Coastguard Worker // that are loaded in memory and caches their file descriptors (this cannot be
43*6777b538SAndroid Build Coastguard Worker // done in official builds because it has security implications).
44*6777b538SAndroid Build Coastguard Worker BASE_EXPORT bool EnableInProcessStackDumping();
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)
47*6777b538SAndroid Build Coastguard Worker // Sets a first-chance callback for the stack dump signal handler. This callback
48*6777b538SAndroid Build Coastguard Worker // is called at the beginning of the signal handler to handle special kinds of
49*6777b538SAndroid Build Coastguard Worker // signals, like out-of-bounds memory accesses in WebAssembly (WebAssembly Trap
50*6777b538SAndroid Build Coastguard Worker // Handler).
51*6777b538SAndroid Build Coastguard Worker // {SetStackDumpFirstChanceCallback} returns {true} if the callback
52*6777b538SAndroid Build Coastguard Worker // has been set correctly. It returns {false} if the stack dump signal handler
53*6777b538SAndroid Build Coastguard Worker // has not been registered with the OS, e.g. because of ASAN.
54*6777b538SAndroid Build Coastguard Worker BASE_EXPORT bool SetStackDumpFirstChanceCallback(bool (*handler)(int,
55*6777b538SAndroid Build Coastguard Worker                                                                  siginfo_t*,
56*6777b538SAndroid Build Coastguard Worker                                                                  void*));
57*6777b538SAndroid Build Coastguard Worker #endif
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker // Returns end of the stack, or 0 if we couldn't get it.
60*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
61*6777b538SAndroid Build Coastguard Worker BASE_EXPORT uintptr_t GetStackEnd();
62*6777b538SAndroid Build Coastguard Worker #endif
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker // A stacktrace can be helpful in debugging. For example, you can include a
65*6777b538SAndroid Build Coastguard Worker // stacktrace member in a object (probably around #ifndef NDEBUG) so that you
66*6777b538SAndroid Build Coastguard Worker // can later see where the given object was created from.
67*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT StackTrace {
68*6777b538SAndroid Build Coastguard Worker  public:
69*6777b538SAndroid Build Coastguard Worker   // LINT.IfChange(max_stack_frames)
70*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
71*6777b538SAndroid Build Coastguard Worker   // TODO(https://crbug.com/925525): Testing indicates that Android has issues
72*6777b538SAndroid Build Coastguard Worker   // with a larger value here, so leave Android at 62.
73*6777b538SAndroid Build Coastguard Worker   static constexpr size_t kMaxTraces = 62;
74*6777b538SAndroid Build Coastguard Worker #else
75*6777b538SAndroid Build Coastguard Worker   // For other platforms, use 250. This seems reasonable without
76*6777b538SAndroid Build Coastguard Worker   // being huge.
77*6777b538SAndroid Build Coastguard Worker   static constexpr size_t kMaxTraces = 250;
78*6777b538SAndroid Build Coastguard Worker #endif
79*6777b538SAndroid Build Coastguard Worker   // LINT.ThenChange(dwarf_line_no.cc:max_stack_frames)
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker   // Creates a stacktrace from the current location.
82*6777b538SAndroid Build Coastguard Worker   StackTrace();
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker   // Creates a stacktrace from the current location, of up to |count| entries.
85*6777b538SAndroid Build Coastguard Worker   // |count| will be limited to at most |kMaxTraces|.
86*6777b538SAndroid Build Coastguard Worker   explicit StackTrace(size_t count);
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker   // Creates a stacktrace from an existing array of instruction
89*6777b538SAndroid Build Coastguard Worker   // pointers (such as returned by Addresses()).  |count| will be
90*6777b538SAndroid Build Coastguard Worker   // limited to at most |kMaxTraces|.
91*6777b538SAndroid Build Coastguard Worker   StackTrace(const void* const* trace, size_t count);
92*6777b538SAndroid Build Coastguard Worker 
93*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
94*6777b538SAndroid Build Coastguard Worker   // Creates a stacktrace for an exception.
95*6777b538SAndroid Build Coastguard Worker   // Note: this function will throw an import not found (StackWalk64) exception
96*6777b538SAndroid Build Coastguard Worker   // on system without dbghelp 5.1.
97*6777b538SAndroid Build Coastguard Worker   StackTrace(_EXCEPTION_POINTERS* exception_pointers);
98*6777b538SAndroid Build Coastguard Worker   StackTrace(const _CONTEXT* context);
99*6777b538SAndroid Build Coastguard Worker #endif
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker   // Returns true if this current test environment is expected to have
102*6777b538SAndroid Build Coastguard Worker   // symbolized frames when printing a stack trace.
103*6777b538SAndroid Build Coastguard Worker   static bool WillSymbolizeToStreamForTesting();
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker   // Copying and assignment are allowed with the default functions.
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker   // Gets an array of instruction pointer values. |*count| will be set to the
108*6777b538SAndroid Build Coastguard Worker   // number of elements in the returned array. Addresses()[0] will contain an
109*6777b538SAndroid Build Coastguard Worker   // address from the leaf function, and Addresses()[count-1] will contain an
110*6777b538SAndroid Build Coastguard Worker   // address from the root function (i.e.; the thread's entry point).
addresses()111*6777b538SAndroid Build Coastguard Worker   span<const void* const> addresses() const {
112*6777b538SAndroid Build Coastguard Worker     return make_span(trace_, count_);
113*6777b538SAndroid Build Coastguard Worker   }
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   // Prints the stack trace to stderr.
116*6777b538SAndroid Build Coastguard Worker   void Print() const;
117*6777b538SAndroid Build Coastguard Worker 
118*6777b538SAndroid Build Coastguard Worker   // Prints the stack trace to stderr, prepending the given string before
119*6777b538SAndroid Build Coastguard Worker   // each output line.
120*6777b538SAndroid Build Coastguard Worker   void PrintWithPrefix(cstring_view prefix_string) const;
121*6777b538SAndroid Build Coastguard Worker 
122*6777b538SAndroid Build Coastguard Worker #if !defined(__UCLIBC__) && !defined(_AIX)
123*6777b538SAndroid Build Coastguard Worker   // Resolves backtrace to symbols and write to stream.
124*6777b538SAndroid Build Coastguard Worker   void OutputToStream(std::ostream* os) const;
125*6777b538SAndroid Build Coastguard Worker   // Resolves backtrace to symbols and write to stream, with the provided
126*6777b538SAndroid Build Coastguard Worker   // prefix string prepended to each line.
127*6777b538SAndroid Build Coastguard Worker   void OutputToStreamWithPrefix(std::ostream* os,
128*6777b538SAndroid Build Coastguard Worker                                 cstring_view prefix_string) const;
129*6777b538SAndroid Build Coastguard Worker #endif
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker   // Resolves backtrace to symbols and returns as string.
132*6777b538SAndroid Build Coastguard Worker   std::string ToString() const;
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker   // Resolves backtrace to symbols and returns as string, prepending the
135*6777b538SAndroid Build Coastguard Worker   // provided prefix string to each line.
136*6777b538SAndroid Build Coastguard Worker   std::string ToStringWithPrefix(cstring_view prefix_string) const;
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker   // Sets a message to be emitted in place of symbolized stack traces. When
139*6777b538SAndroid Build Coastguard Worker   // such a message is provided, collection and symbolization of stack traces
140*6777b538SAndroid Build Coastguard Worker   // is suppressed. Suppression is cancelled if `message` is empty.
141*6777b538SAndroid Build Coastguard Worker   static void SuppressStackTracesWithMessageForTesting(std::string message);
142*6777b538SAndroid Build Coastguard Worker 
143*6777b538SAndroid Build Coastguard Worker  private:
144*6777b538SAndroid Build Coastguard Worker   // Prints `message` with an optional prefix.
145*6777b538SAndroid Build Coastguard Worker   static void PrintMessageWithPrefix(cstring_view prefix_string,
146*6777b538SAndroid Build Coastguard Worker                                      cstring_view message);
147*6777b538SAndroid Build Coastguard Worker 
148*6777b538SAndroid Build Coastguard Worker   void PrintWithPrefixImpl(cstring_view prefix_string) const;
149*6777b538SAndroid Build Coastguard Worker #if !defined(__UCLIBC__) && !defined(_AIX)
150*6777b538SAndroid Build Coastguard Worker   void OutputToStreamWithPrefixImpl(std::ostream* os,
151*6777b538SAndroid Build Coastguard Worker                                     cstring_view prefix_string) const;
152*6777b538SAndroid Build Coastguard Worker #endif
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker   // Returns true if generation of symbolized stack traces is to be suppressed.
155*6777b538SAndroid Build Coastguard Worker   static bool ShouldSuppressOutput();
156*6777b538SAndroid Build Coastguard Worker 
157*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
158*6777b538SAndroid Build Coastguard Worker   void InitTrace(const _CONTEXT* context_record);
159*6777b538SAndroid Build Coastguard Worker #endif
160*6777b538SAndroid Build Coastguard Worker 
161*6777b538SAndroid Build Coastguard Worker   const void* trace_[kMaxTraces];
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker   // The number of valid frames in |trace_|, or 0 if collection was suppressed.
164*6777b538SAndroid Build Coastguard Worker   size_t count_ = 0;
165*6777b538SAndroid Build Coastguard Worker };
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker // Forwards to StackTrace::OutputToStream().
168*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& os, const StackTrace& s);
169*6777b538SAndroid Build Coastguard Worker 
170*6777b538SAndroid Build Coastguard Worker // Record a stack trace with up to |count| frames into |trace|. Returns the
171*6777b538SAndroid Build Coastguard Worker // number of frames read.
172*6777b538SAndroid Build Coastguard Worker BASE_EXPORT size_t CollectStackTrace(const void** trace, size_t count);
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker // A helper for tests that must either override the default suppression of
175*6777b538SAndroid Build Coastguard Worker // symbolized stack traces in death tests, or the default generation of them in
176*6777b538SAndroid Build Coastguard Worker // normal tests.
177*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT OverrideStackTraceOutputForTesting {
178*6777b538SAndroid Build Coastguard Worker  public:
179*6777b538SAndroid Build Coastguard Worker   enum class Mode {
180*6777b538SAndroid Build Coastguard Worker     kUnset,
181*6777b538SAndroid Build Coastguard Worker     kForceOutput,
182*6777b538SAndroid Build Coastguard Worker     kSuppressOutput,
183*6777b538SAndroid Build Coastguard Worker   };
184*6777b538SAndroid Build Coastguard Worker   explicit OverrideStackTraceOutputForTesting(Mode mode);
185*6777b538SAndroid Build Coastguard Worker   OverrideStackTraceOutputForTesting(
186*6777b538SAndroid Build Coastguard Worker       const OverrideStackTraceOutputForTesting&) = delete;
187*6777b538SAndroid Build Coastguard Worker   OverrideStackTraceOutputForTesting& operator=(
188*6777b538SAndroid Build Coastguard Worker       const OverrideStackTraceOutputForTesting&) = delete;
189*6777b538SAndroid Build Coastguard Worker   ~OverrideStackTraceOutputForTesting();
190*6777b538SAndroid Build Coastguard Worker };
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
193*6777b538SAndroid Build Coastguard Worker 
194*6777b538SAndroid Build Coastguard Worker // For stack scanning to be efficient it's very important for the thread to
195*6777b538SAndroid Build Coastguard Worker // be started by Chrome. In that case we naturally terminate unwinding once
196*6777b538SAndroid Build Coastguard Worker // we reach the origin of the stack (i.e. GetStackEnd()). If the thread is
197*6777b538SAndroid Build Coastguard Worker // not started by Chrome (e.g. Android's main thread), then we end up always
198*6777b538SAndroid Build Coastguard Worker // scanning area at the origin of the stack, wasting time and not finding any
199*6777b538SAndroid Build Coastguard Worker // frames (since Android libraries don't have frame pointers). Scanning is not
200*6777b538SAndroid Build Coastguard Worker // enabled on other posix platforms due to legacy reasons.
201*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
202*6777b538SAndroid Build Coastguard Worker constexpr bool kEnableScanningByDefault = true;
203*6777b538SAndroid Build Coastguard Worker #else
204*6777b538SAndroid Build Coastguard Worker constexpr bool kEnableScanningByDefault = false;
205*6777b538SAndroid Build Coastguard Worker #endif
206*6777b538SAndroid Build Coastguard Worker 
207*6777b538SAndroid Build Coastguard Worker // Traces the stack by using frame pointers. This function is faster but less
208*6777b538SAndroid Build Coastguard Worker // reliable than StackTrace. It should work for debug and profiling builds,
209*6777b538SAndroid Build Coastguard Worker // but not for release builds (although there are some exceptions).
210*6777b538SAndroid Build Coastguard Worker //
211*6777b538SAndroid Build Coastguard Worker // Writes at most |max_depth| frames (instruction pointers) into |out_trace|
212*6777b538SAndroid Build Coastguard Worker // after skipping |skip_initial| frames. Note that the function itself is not
213*6777b538SAndroid Build Coastguard Worker // added to the trace so |skip_initial| should be 0 in most cases.
214*6777b538SAndroid Build Coastguard Worker // Returns number of frames written. |enable_scanning| enables scanning on
215*6777b538SAndroid Build Coastguard Worker // platforms that do not enable scanning by default.
216*6777b538SAndroid Build Coastguard Worker BASE_EXPORT size_t
217*6777b538SAndroid Build Coastguard Worker TraceStackFramePointers(const void** out_trace,
218*6777b538SAndroid Build Coastguard Worker                         size_t max_depth,
219*6777b538SAndroid Build Coastguard Worker                         size_t skip_initial,
220*6777b538SAndroid Build Coastguard Worker                         bool enable_scanning = kEnableScanningByDefault);
221*6777b538SAndroid Build Coastguard Worker 
222*6777b538SAndroid Build Coastguard Worker // Same as above function, but allows to pass in frame pointer and stack end
223*6777b538SAndroid Build Coastguard Worker // address for unwinding. This is useful when unwinding based on a copied stack
224*6777b538SAndroid Build Coastguard Worker // segment. Note that the client has to take care of rewriting all the pointers
225*6777b538SAndroid Build Coastguard Worker // in the stack pointing within the stack to point to the copied addresses.
226*6777b538SAndroid Build Coastguard Worker BASE_EXPORT size_t TraceStackFramePointersFromBuffer(
227*6777b538SAndroid Build Coastguard Worker     uintptr_t fp,
228*6777b538SAndroid Build Coastguard Worker     uintptr_t stack_end,
229*6777b538SAndroid Build Coastguard Worker     const void** out_trace,
230*6777b538SAndroid Build Coastguard Worker     size_t max_depth,
231*6777b538SAndroid Build Coastguard Worker     size_t skip_initial,
232*6777b538SAndroid Build Coastguard Worker     bool enable_scanning = kEnableScanningByDefault);
233*6777b538SAndroid Build Coastguard Worker 
234*6777b538SAndroid Build Coastguard Worker // Links stack frame |fp| to |parent_fp|, so that during stack unwinding
235*6777b538SAndroid Build Coastguard Worker // TraceStackFramePointers() visits |parent_fp| after visiting |fp|.
236*6777b538SAndroid Build Coastguard Worker // Both frame pointers must come from __builtin_frame_address().
237*6777b538SAndroid Build Coastguard Worker // Destructor restores original linkage of |fp| to avoid corrupting caller's
238*6777b538SAndroid Build Coastguard Worker // frame register on return.
239*6777b538SAndroid Build Coastguard Worker //
240*6777b538SAndroid Build Coastguard Worker // This class can be used to repair broken stack frame chain in cases
241*6777b538SAndroid Build Coastguard Worker // when execution flow goes into code built without frame pointers:
242*6777b538SAndroid Build Coastguard Worker //
243*6777b538SAndroid Build Coastguard Worker // void DoWork() {
244*6777b538SAndroid Build Coastguard Worker //   Call_SomeLibrary();
245*6777b538SAndroid Build Coastguard Worker // }
246*6777b538SAndroid Build Coastguard Worker // static __thread void*  g_saved_fp;
247*6777b538SAndroid Build Coastguard Worker // void Call_SomeLibrary() {
248*6777b538SAndroid Build Coastguard Worker //   g_saved_fp = __builtin_frame_address(0);
249*6777b538SAndroid Build Coastguard Worker //   some_library_call(...); // indirectly calls SomeLibrary_Callback()
250*6777b538SAndroid Build Coastguard Worker // }
251*6777b538SAndroid Build Coastguard Worker // void SomeLibrary_Callback() {
252*6777b538SAndroid Build Coastguard Worker //   ScopedStackFrameLinker linker(__builtin_frame_address(0), g_saved_fp);
253*6777b538SAndroid Build Coastguard Worker //   ...
254*6777b538SAndroid Build Coastguard Worker //   TraceStackFramePointers(...);
255*6777b538SAndroid Build Coastguard Worker // }
256*6777b538SAndroid Build Coastguard Worker //
257*6777b538SAndroid Build Coastguard Worker // This produces the following trace:
258*6777b538SAndroid Build Coastguard Worker //
259*6777b538SAndroid Build Coastguard Worker // #0 SomeLibrary_Callback()
260*6777b538SAndroid Build Coastguard Worker // #1 <address of the code inside SomeLibrary that called #0>
261*6777b538SAndroid Build Coastguard Worker // #2 DoWork()
262*6777b538SAndroid Build Coastguard Worker // ...rest of the trace...
263*6777b538SAndroid Build Coastguard Worker //
264*6777b538SAndroid Build Coastguard Worker // SomeLibrary doesn't use frame pointers, so when SomeLibrary_Callback()
265*6777b538SAndroid Build Coastguard Worker // is called, stack frame register contains bogus value that becomes callback'
266*6777b538SAndroid Build Coastguard Worker // parent frame address. Without ScopedStackFrameLinker unwinding would've
267*6777b538SAndroid Build Coastguard Worker // stopped at that bogus frame address yielding just two first frames (#0, #1).
268*6777b538SAndroid Build Coastguard Worker // ScopedStackFrameLinker overwrites callback's parent frame address with
269*6777b538SAndroid Build Coastguard Worker // Call_SomeLibrary's frame, so unwinder produces full trace without even
270*6777b538SAndroid Build Coastguard Worker // noticing that stack frame chain was broken.
271*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ScopedStackFrameLinker {
272*6777b538SAndroid Build Coastguard Worker  public:
273*6777b538SAndroid Build Coastguard Worker   ScopedStackFrameLinker(void* fp, void* parent_fp);
274*6777b538SAndroid Build Coastguard Worker 
275*6777b538SAndroid Build Coastguard Worker   ScopedStackFrameLinker(const ScopedStackFrameLinker&) = delete;
276*6777b538SAndroid Build Coastguard Worker   ScopedStackFrameLinker& operator=(const ScopedStackFrameLinker&) = delete;
277*6777b538SAndroid Build Coastguard Worker 
278*6777b538SAndroid Build Coastguard Worker   ~ScopedStackFrameLinker();
279*6777b538SAndroid Build Coastguard Worker 
280*6777b538SAndroid Build Coastguard Worker  private:
281*6777b538SAndroid Build Coastguard Worker   raw_ptr<void> fp_;
282*6777b538SAndroid Build Coastguard Worker   raw_ptr<void> parent_fp_;
283*6777b538SAndroid Build Coastguard Worker   raw_ptr<void> original_parent_fp_;
284*6777b538SAndroid Build Coastguard Worker };
285*6777b538SAndroid Build Coastguard Worker 
286*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
287*6777b538SAndroid Build Coastguard Worker 
288*6777b538SAndroid Build Coastguard Worker namespace internal {
289*6777b538SAndroid Build Coastguard Worker 
290*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
291*6777b538SAndroid Build Coastguard Worker // POSIX doesn't define any async-signal safe function for converting
292*6777b538SAndroid Build Coastguard Worker // an integer to ASCII. We'll have to define our own version.
293*6777b538SAndroid Build Coastguard Worker // itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the
294*6777b538SAndroid Build Coastguard Worker // conversion was successful or NULL otherwise. It never writes more than "sz"
295*6777b538SAndroid Build Coastguard Worker // bytes. Output will be truncated as needed, and a NUL character is always
296*6777b538SAndroid Build Coastguard Worker // appended.
297*6777b538SAndroid Build Coastguard Worker BASE_EXPORT char *itoa_r(intptr_t i,
298*6777b538SAndroid Build Coastguard Worker                          char *buf,
299*6777b538SAndroid Build Coastguard Worker                          size_t sz,
300*6777b538SAndroid Build Coastguard Worker                          int base,
301*6777b538SAndroid Build Coastguard Worker                          size_t padding);
302*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
303*6777b538SAndroid Build Coastguard Worker 
304*6777b538SAndroid Build Coastguard Worker }  // namespace internal
305*6777b538SAndroid Build Coastguard Worker 
306*6777b538SAndroid Build Coastguard Worker }  // namespace debug
307*6777b538SAndroid Build Coastguard Worker }  // namespace base
308*6777b538SAndroid Build Coastguard Worker 
309*6777b538SAndroid Build Coastguard Worker #endif  // BASE_DEBUG_STACK_TRACE_H_
310