xref: /aosp_15_r20/external/libchrome/base/debug/stack_trace.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_DEBUG_STACK_TRACE_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_DEBUG_STACK_TRACE_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include <iosfwd>
11*635a8641SAndroid Build Coastguard Worker #include <string>
12*635a8641SAndroid Build Coastguard Worker 
13*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/debug/debugging_buildflags.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
16*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
17*635a8641SAndroid Build Coastguard Worker 
18*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
19*635a8641SAndroid Build Coastguard Worker #include <unistd.h>
20*635a8641SAndroid Build Coastguard Worker #endif
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
23*635a8641SAndroid Build Coastguard Worker struct _EXCEPTION_POINTERS;
24*635a8641SAndroid Build Coastguard Worker struct _CONTEXT;
25*635a8641SAndroid Build Coastguard Worker #endif
26*635a8641SAndroid Build Coastguard Worker 
27*635a8641SAndroid Build Coastguard Worker namespace base {
28*635a8641SAndroid Build Coastguard Worker namespace debug {
29*635a8641SAndroid Build Coastguard Worker 
30*635a8641SAndroid Build Coastguard Worker // Enables stack dump to console output on exception and signals.
31*635a8641SAndroid Build Coastguard Worker // When enabled, the process will quit immediately. This is meant to be used in
32*635a8641SAndroid Build Coastguard Worker // unit_tests only! This is not thread-safe: only call from main thread.
33*635a8641SAndroid Build Coastguard Worker // In sandboxed processes, this has to be called before the sandbox is turned
34*635a8641SAndroid Build Coastguard Worker // on.
35*635a8641SAndroid Build Coastguard Worker // Calling this function on Linux opens /proc/self/maps and caches its
36*635a8641SAndroid Build Coastguard Worker // contents. In non-official builds, this function also opens the object files
37*635a8641SAndroid Build Coastguard Worker // that are loaded in memory and caches their file descriptors (this cannot be
38*635a8641SAndroid Build Coastguard Worker // done in official builds because it has security implications).
39*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool EnableInProcessStackDumping();
40*635a8641SAndroid Build Coastguard Worker 
41*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
42*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void SetStackDumpFirstChanceCallback(bool (*handler)(int,
43*635a8641SAndroid Build Coastguard Worker                                                                  void*,
44*635a8641SAndroid Build Coastguard Worker                                                                  void*));
45*635a8641SAndroid Build Coastguard Worker #endif
46*635a8641SAndroid Build Coastguard Worker 
47*635a8641SAndroid Build Coastguard Worker // Returns end of the stack, or 0 if we couldn't get it.
48*635a8641SAndroid Build Coastguard Worker #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
49*635a8641SAndroid Build Coastguard Worker BASE_EXPORT uintptr_t GetStackEnd();
50*635a8641SAndroid Build Coastguard Worker #endif
51*635a8641SAndroid Build Coastguard Worker 
52*635a8641SAndroid Build Coastguard Worker // A stacktrace can be helpful in debugging. For example, you can include a
53*635a8641SAndroid Build Coastguard Worker // stacktrace member in a object (probably around #ifndef NDEBUG) so that you
54*635a8641SAndroid Build Coastguard Worker // can later see where the given object was created from.
55*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT StackTrace {
56*635a8641SAndroid Build Coastguard Worker  public:
57*635a8641SAndroid Build Coastguard Worker   // Creates a stacktrace from the current location.
58*635a8641SAndroid Build Coastguard Worker   StackTrace();
59*635a8641SAndroid Build Coastguard Worker 
60*635a8641SAndroid Build Coastguard Worker   // Creates a stacktrace from the current location, of up to |count| entries.
61*635a8641SAndroid Build Coastguard Worker   // |count| will be limited to at most |kMaxTraces|.
62*635a8641SAndroid Build Coastguard Worker   explicit StackTrace(size_t count);
63*635a8641SAndroid Build Coastguard Worker 
64*635a8641SAndroid Build Coastguard Worker   // Creates a stacktrace from an existing array of instruction
65*635a8641SAndroid Build Coastguard Worker   // pointers (such as returned by Addresses()).  |count| will be
66*635a8641SAndroid Build Coastguard Worker   // limited to at most |kMaxTraces|.
67*635a8641SAndroid Build Coastguard Worker   StackTrace(const void* const* trace, size_t count);
68*635a8641SAndroid Build Coastguard Worker 
69*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
70*635a8641SAndroid Build Coastguard Worker   // Creates a stacktrace for an exception.
71*635a8641SAndroid Build Coastguard Worker   // Note: this function will throw an import not found (StackWalk64) exception
72*635a8641SAndroid Build Coastguard Worker   // on system without dbghelp 5.1.
73*635a8641SAndroid Build Coastguard Worker   StackTrace(_EXCEPTION_POINTERS* exception_pointers);
74*635a8641SAndroid Build Coastguard Worker   StackTrace(const _CONTEXT* context);
75*635a8641SAndroid Build Coastguard Worker #endif
76*635a8641SAndroid Build Coastguard Worker 
77*635a8641SAndroid Build Coastguard Worker   // Copying and assignment are allowed with the default functions.
78*635a8641SAndroid Build Coastguard Worker 
79*635a8641SAndroid Build Coastguard Worker   // Gets an array of instruction pointer values. |*count| will be set to the
80*635a8641SAndroid Build Coastguard Worker   // number of elements in the returned array.
81*635a8641SAndroid Build Coastguard Worker   const void* const* Addresses(size_t* count) const;
82*635a8641SAndroid Build Coastguard Worker 
83*635a8641SAndroid Build Coastguard Worker   // Prints the stack trace to stderr.
84*635a8641SAndroid Build Coastguard Worker   void Print() const;
85*635a8641SAndroid Build Coastguard Worker 
86*635a8641SAndroid Build Coastguard Worker #if !defined(__UCLIBC__) & !defined(_AIX)
87*635a8641SAndroid Build Coastguard Worker   // Resolves backtrace to symbols and write to stream.
88*635a8641SAndroid Build Coastguard Worker   void OutputToStream(std::ostream* os) const;
89*635a8641SAndroid Build Coastguard Worker #endif
90*635a8641SAndroid Build Coastguard Worker 
91*635a8641SAndroid Build Coastguard Worker   // Resolves backtrace to symbols and returns as string.
92*635a8641SAndroid Build Coastguard Worker   std::string ToString() const;
93*635a8641SAndroid Build Coastguard Worker 
94*635a8641SAndroid Build Coastguard Worker  private:
95*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
96*635a8641SAndroid Build Coastguard Worker   void InitTrace(const _CONTEXT* context_record);
97*635a8641SAndroid Build Coastguard Worker #endif
98*635a8641SAndroid Build Coastguard Worker 
99*635a8641SAndroid Build Coastguard Worker   // From http://msdn.microsoft.com/en-us/library/bb204633.aspx,
100*635a8641SAndroid Build Coastguard Worker   // the sum of FramesToSkip and FramesToCapture must be less than 63,
101*635a8641SAndroid Build Coastguard Worker   // so set it to 62. Even if on POSIX it could be a larger value, it usually
102*635a8641SAndroid Build Coastguard Worker   // doesn't give much more information.
103*635a8641SAndroid Build Coastguard Worker   static const int kMaxTraces = 62;
104*635a8641SAndroid Build Coastguard Worker 
105*635a8641SAndroid Build Coastguard Worker   void* trace_[kMaxTraces];
106*635a8641SAndroid Build Coastguard Worker 
107*635a8641SAndroid Build Coastguard Worker   // The number of valid frames in |trace_|.
108*635a8641SAndroid Build Coastguard Worker   size_t count_;
109*635a8641SAndroid Build Coastguard Worker };
110*635a8641SAndroid Build Coastguard Worker 
111*635a8641SAndroid Build Coastguard Worker #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
112*635a8641SAndroid Build Coastguard Worker // Traces the stack by using frame pointers. This function is faster but less
113*635a8641SAndroid Build Coastguard Worker // reliable than StackTrace. It should work for debug and profiling builds,
114*635a8641SAndroid Build Coastguard Worker // but not for release builds (although there are some exceptions).
115*635a8641SAndroid Build Coastguard Worker //
116*635a8641SAndroid Build Coastguard Worker // Writes at most |max_depth| frames (instruction pointers) into |out_trace|
117*635a8641SAndroid Build Coastguard Worker // after skipping |skip_initial| frames. Note that the function itself is not
118*635a8641SAndroid Build Coastguard Worker // added to the trace so |skip_initial| should be 0 in most cases.
119*635a8641SAndroid Build Coastguard Worker // Returns number of frames written.
120*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t TraceStackFramePointers(const void** out_trace,
121*635a8641SAndroid Build Coastguard Worker                                            size_t max_depth,
122*635a8641SAndroid Build Coastguard Worker                                            size_t skip_initial);
123*635a8641SAndroid Build Coastguard Worker 
124*635a8641SAndroid Build Coastguard Worker // Links stack frame |fp| to |parent_fp|, so that during stack unwinding
125*635a8641SAndroid Build Coastguard Worker // TraceStackFramePointers() visits |parent_fp| after visiting |fp|.
126*635a8641SAndroid Build Coastguard Worker // Both frame pointers must come from __builtin_frame_address().
127*635a8641SAndroid Build Coastguard Worker // Destructor restores original linkage of |fp| to avoid corrupting caller's
128*635a8641SAndroid Build Coastguard Worker // frame register on return.
129*635a8641SAndroid Build Coastguard Worker //
130*635a8641SAndroid Build Coastguard Worker // This class can be used to repair broken stack frame chain in cases
131*635a8641SAndroid Build Coastguard Worker // when execution flow goes into code built without frame pointers:
132*635a8641SAndroid Build Coastguard Worker //
133*635a8641SAndroid Build Coastguard Worker // void DoWork() {
134*635a8641SAndroid Build Coastguard Worker //   Call_SomeLibrary();
135*635a8641SAndroid Build Coastguard Worker // }
136*635a8641SAndroid Build Coastguard Worker // static __thread void*  g_saved_fp;
137*635a8641SAndroid Build Coastguard Worker // void Call_SomeLibrary() {
138*635a8641SAndroid Build Coastguard Worker //   g_saved_fp = __builtin_frame_address(0);
139*635a8641SAndroid Build Coastguard Worker //   some_library_call(...); // indirectly calls SomeLibrary_Callback()
140*635a8641SAndroid Build Coastguard Worker // }
141*635a8641SAndroid Build Coastguard Worker // void SomeLibrary_Callback() {
142*635a8641SAndroid Build Coastguard Worker //   ScopedStackFrameLinker linker(__builtin_frame_address(0), g_saved_fp);
143*635a8641SAndroid Build Coastguard Worker //   ...
144*635a8641SAndroid Build Coastguard Worker //   TraceStackFramePointers(...);
145*635a8641SAndroid Build Coastguard Worker // }
146*635a8641SAndroid Build Coastguard Worker //
147*635a8641SAndroid Build Coastguard Worker // This produces the following trace:
148*635a8641SAndroid Build Coastguard Worker //
149*635a8641SAndroid Build Coastguard Worker // #0 SomeLibrary_Callback()
150*635a8641SAndroid Build Coastguard Worker // #1 <address of the code inside SomeLibrary that called #0>
151*635a8641SAndroid Build Coastguard Worker // #2 DoWork()
152*635a8641SAndroid Build Coastguard Worker // ...rest of the trace...
153*635a8641SAndroid Build Coastguard Worker //
154*635a8641SAndroid Build Coastguard Worker // SomeLibrary doesn't use frame pointers, so when SomeLibrary_Callback()
155*635a8641SAndroid Build Coastguard Worker // is called, stack frame register contains bogus value that becomes callback'
156*635a8641SAndroid Build Coastguard Worker // parent frame address. Without ScopedStackFrameLinker unwinding would've
157*635a8641SAndroid Build Coastguard Worker // stopped at that bogus frame address yielding just two first frames (#0, #1).
158*635a8641SAndroid Build Coastguard Worker // ScopedStackFrameLinker overwrites callback's parent frame address with
159*635a8641SAndroid Build Coastguard Worker // Call_SomeLibrary's frame, so unwinder produces full trace without even
160*635a8641SAndroid Build Coastguard Worker // noticing that stack frame chain was broken.
161*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ScopedStackFrameLinker {
162*635a8641SAndroid Build Coastguard Worker  public:
163*635a8641SAndroid Build Coastguard Worker   ScopedStackFrameLinker(void* fp, void* parent_fp);
164*635a8641SAndroid Build Coastguard Worker   ~ScopedStackFrameLinker();
165*635a8641SAndroid Build Coastguard Worker 
166*635a8641SAndroid Build Coastguard Worker  private:
167*635a8641SAndroid Build Coastguard Worker   void* fp_;
168*635a8641SAndroid Build Coastguard Worker   void* parent_fp_;
169*635a8641SAndroid Build Coastguard Worker   void* original_parent_fp_;
170*635a8641SAndroid Build Coastguard Worker 
171*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ScopedStackFrameLinker);
172*635a8641SAndroid Build Coastguard Worker };
173*635a8641SAndroid Build Coastguard Worker 
174*635a8641SAndroid Build Coastguard Worker #endif  // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
175*635a8641SAndroid Build Coastguard Worker 
176*635a8641SAndroid Build Coastguard Worker namespace internal {
177*635a8641SAndroid Build Coastguard Worker 
178*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX) && !defined(OS_ANDROID)
179*635a8641SAndroid Build Coastguard Worker // POSIX doesn't define any async-signal safe function for converting
180*635a8641SAndroid Build Coastguard Worker // an integer to ASCII. We'll have to define our own version.
181*635a8641SAndroid Build Coastguard Worker // itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the
182*635a8641SAndroid Build Coastguard Worker // conversion was successful or NULL otherwise. It never writes more than "sz"
183*635a8641SAndroid Build Coastguard Worker // bytes. Output will be truncated as needed, and a NUL character is always
184*635a8641SAndroid Build Coastguard Worker // appended.
185*635a8641SAndroid Build Coastguard Worker BASE_EXPORT char *itoa_r(intptr_t i,
186*635a8641SAndroid Build Coastguard Worker                          char *buf,
187*635a8641SAndroid Build Coastguard Worker                          size_t sz,
188*635a8641SAndroid Build Coastguard Worker                          int base,
189*635a8641SAndroid Build Coastguard Worker                          size_t padding);
190*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_POSIX) && !defined(OS_ANDROID)
191*635a8641SAndroid Build Coastguard Worker 
192*635a8641SAndroid Build Coastguard Worker }  // namespace internal
193*635a8641SAndroid Build Coastguard Worker 
194*635a8641SAndroid Build Coastguard Worker }  // namespace debug
195*635a8641SAndroid Build Coastguard Worker }  // namespace base
196*635a8641SAndroid Build Coastguard Worker 
197*635a8641SAndroid Build Coastguard Worker #endif  // BASE_DEBUG_STACK_TRACE_H_
198