blob: fd3bcb30cb83e37b6cf162b683415cf3c1888c04 [file] [log] [blame]
[email protected]e645c7a2012-07-25 21:43:441// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]58580352010-10-26 04:07:502// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_DEBUG_STACK_TRACE_H_
6#define BASE_DEBUG_STACK_TRACE_H_
[email protected]58580352010-10-26 04:07:507
aviebe805c2015-12-24 08:20:288#include <stddef.h>
9
[email protected]58580352010-10-26 04:07:5010#include <iosfwd>
[email protected]d4114ba2011-10-12 16:13:4011#include <string>
[email protected]58580352010-10-26 04:07:5012
[email protected]0bea7252011-08-05 15:34:0013#include "base/base_export.h"
erikchenf7c8a0d2017-04-06 21:15:2714#include "base/debug/debugging_flags.h"
dskibaa8c951e2016-10-25 23:39:1115#include "base/macros.h"
[email protected]58580352010-10-26 04:07:5016#include "build/build_config.h"
17
[email protected]47c45562012-11-17 14:33:2518#if defined(OS_POSIX)
19#include <unistd.h>
20#endif
21
[email protected]58580352010-10-26 04:07:5022#if defined(OS_WIN)
23struct _EXCEPTION_POINTERS;
wittman7808da72015-02-03 17:46:5124struct _CONTEXT;
[email protected]58580352010-10-26 04:07:5025#endif
26
[email protected]58580352010-10-26 04:07:5027namespace base {
28namespace debug {
29
[email protected]11b93faa2012-11-01 21:58:3030// Enables stack dump to console output on exception and signals.
31// When enabled, the process will quit immediately. This is meant to be used in
32// unit_tests only! This is not thread-safe: only call from main thread.
jam79dc59a2015-08-17 03:38:1633// In sandboxed processes, this has to be called before the sandbox is turned
34// on.
[email protected]ad9a0122014-03-22 00:34:5235// Calling this function on Linux opens /proc/self/maps and caches its
jam79dc59a2015-08-17 03:38:1636// contents. In non-official builds, this function also opens the object files
37// that are loaded in memory and caches their file descriptors (this cannot be
[email protected]ad9a0122014-03-22 00:34:5238// done in official builds because it has security implications).
jam79dc59a2015-08-17 03:38:1639BASE_EXPORT bool EnableInProcessStackDumping();
[email protected]ad9a0122014-03-22 00:34:5240
Eric Holkdc499db2017-07-17 17:57:3541#if defined(OS_POSIX)
42BASE_EXPORT void SetStackDumpFirstChanceCallback(bool (*handler)(int,
43 void*,
44 void*));
45#endif
46
erikchend6b2b822017-02-22 21:10:3147// Returns end of the stack, or 0 if we couldn't get it.
erikchenf7c8a0d2017-04-06 21:15:2748#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
erikchend6b2b822017-02-22 21:10:3149BASE_EXPORT uintptr_t GetStackEnd();
50#endif
51
[email protected]58580352010-10-26 04:07:5052// A stacktrace can be helpful in debugging. For example, you can include a
53// stacktrace member in a object (probably around #ifndef NDEBUG) so that you
54// can later see where the given object was created from.
[email protected]0bea7252011-08-05 15:34:0055class BASE_EXPORT StackTrace {
[email protected]58580352010-10-26 04:07:5056 public:
57 // Creates a stacktrace from the current location.
58 StackTrace();
59
wez73f8d7e2017-01-29 06:18:1360 // Creates a stacktrace from the current location, of up to |count| entries.
61 // |count| will be limited to at most |kMaxTraces|.
62 explicit StackTrace(size_t count);
63
[email protected]f01ae9812011-08-30 19:33:0464 // Creates a stacktrace from an existing array of instruction
65 // pointers (such as returned by Addresses()). |count| will be
wez73f8d7e2017-01-29 06:18:1366 // limited to at most |kMaxTraces|.
[email protected]f01ae9812011-08-30 19:33:0467 StackTrace(const void* const* trace, size_t count);
68
[email protected]58580352010-10-26 04:07:5069#if defined(OS_WIN)
70 // Creates a stacktrace for an exception.
71 // Note: this function will throw an import not found (StackWalk64) exception
72 // on system without dbghelp 5.1.
jam79dc59a2015-08-17 03:38:1673 StackTrace(_EXCEPTION_POINTERS* exception_pointers);
rnk0565cdd62015-10-06 16:48:3074 StackTrace(const _CONTEXT* context);
[email protected]58580352010-10-26 04:07:5075#endif
76
77 // Copying and assignment are allowed with the default functions.
78
[email protected]58580352010-10-26 04:07:5079 // Gets an array of instruction pointer values. |*count| will be set to the
80 // number of elements in the returned array.
[email protected]501dfc42011-04-14 16:34:0081 const void* const* Addresses(size_t* count) const;
[email protected]58580352010-10-26 04:07:5082
[email protected]5ddbf1c2013-08-29 01:59:3883 // Prints the stack trace to stderr.
84 void Print() const;
[email protected]58580352010-10-26 04:07:5085
rayb0088ee52017-04-26 22:35:0886#if !defined(__UCLIBC__) & !defined(_AIX)
[email protected]58580352010-10-26 04:07:5087 // Resolves backtrace to symbols and write to stream.
[email protected]501dfc42011-04-14 16:34:0088 void OutputToStream(std::ostream* os) const;
[email protected]816e50452014-04-09 22:29:3889#endif
[email protected]58580352010-10-26 04:07:5090
[email protected]d4114ba2011-10-12 16:13:4091 // Resolves backtrace to symbols and returns as string.
92 std::string ToString() const;
93
[email protected]58580352010-10-26 04:07:5094 private:
wittman7808da72015-02-03 17:46:5195#if defined(OS_WIN)
rnk0565cdd62015-10-06 16:48:3096 void InitTrace(const _CONTEXT* context_record);
wittman7808da72015-02-03 17:46:5197#endif
98
[email protected]58580352010-10-26 04:07:5099 // From http://msdn.microsoft.com/en-us/library/bb204633.aspx,
100 // the sum of FramesToSkip and FramesToCapture must be less than 63,
101 // so set it to 62. Even if on POSIX it could be a larger value, it usually
102 // doesn't give much more information.
103 static const int kMaxTraces = 62;
104
105 void* trace_[kMaxTraces];
[email protected]e645c7a2012-07-25 21:43:44106
107 // The number of valid frames in |trace_|.
108 size_t count_;
[email protected]58580352010-10-26 04:07:50109};
110
erikchenf7c8a0d2017-04-06 21:15:27111#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
dskiba79080da02016-04-23 00:10:27112// Traces the stack by using frame pointers. This function is faster but less
113// reliable than StackTrace. It should work for debug and profiling builds,
114// but not for release builds (although there are some exceptions).
115//
116// Writes at most |max_depth| frames (instruction pointers) into |out_trace|
117// after skipping |skip_initial| frames. Note that the function itself is not
118// added to the trace so |skip_initial| should be 0 in most cases.
119// Returns number of frames written.
120BASE_EXPORT size_t TraceStackFramePointers(const void** out_trace,
121 size_t max_depth,
122 size_t skip_initial);
dskibaa8c951e2016-10-25 23:39:11123
124// Links stack frame |fp| to |parent_fp|, so that during stack unwinding
125// TraceStackFramePointers() visits |parent_fp| after visiting |fp|.
126// Both frame pointers must come from __builtin_frame_address().
127// Destructor restores original linkage of |fp| to avoid corrupting caller's
128// frame register on return.
129//
130// This class can be used to repair broken stack frame chain in cases
131// when execution flow goes into code built without frame pointers:
132//
133// void DoWork() {
134// Call_SomeLibrary();
135// }
136// static __thread void* g_saved_fp;
137// void Call_SomeLibrary() {
138// g_saved_fp = __builtin_frame_address(0);
139// some_library_call(...); // indirectly calls SomeLibrary_Callback()
140// }
141// void SomeLibrary_Callback() {
142// ScopedStackFrameLinker linker(__builtin_frame_address(0), g_saved_fp);
143// ...
144// TraceStackFramePointers(...);
145// }
146//
147// This produces the following trace:
148//
149// #0 SomeLibrary_Callback()
150// #1 <address of the code inside SomeLibrary that called #0>
151// #2 DoWork()
152// ...rest of the trace...
153//
154// SomeLibrary doesn't use frame pointers, so when SomeLibrary_Callback()
155// is called, stack frame register contains bogus value that becomes callback'
156// parent frame address. Without ScopedStackFrameLinker unwinding would've
157// stopped at that bogus frame address yielding just two first frames (#0, #1).
158// ScopedStackFrameLinker overwrites callback's parent frame address with
159// Call_SomeLibrary's frame, so unwinder produces full trace without even
160// noticing that stack frame chain was broken.
161class BASE_EXPORT ScopedStackFrameLinker {
162 public:
163 ScopedStackFrameLinker(void* fp, void* parent_fp);
164 ~ScopedStackFrameLinker();
165
166 private:
167 void* fp_;
168 void* parent_fp_;
169 void* original_parent_fp_;
170
171 DISALLOW_COPY_AND_ASSIGN(ScopedStackFrameLinker);
172};
173
erikchenf7c8a0d2017-04-06 21:15:27174#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
dskiba79080da02016-04-23 00:10:27175
[email protected]1e218b72012-11-14 19:32:23176namespace internal {
177
178#if defined(OS_POSIX) && !defined(OS_ANDROID)
179// POSIX doesn't define any async-signal safe function for converting
180// an integer to ASCII. We'll have to define our own version.
181// itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the
182// conversion was successful or NULL otherwise. It never writes more than "sz"
183// bytes. Output will be truncated as needed, and a NUL character is always
184// appended.
[email protected]22d5b9822013-01-10 18:21:52185BASE_EXPORT char *itoa_r(intptr_t i,
186 char *buf,
187 size_t sz,
188 int base,
189 size_t padding);
[email protected]1e218b72012-11-14 19:32:23190#endif // defined(OS_POSIX) && !defined(OS_ANDROID)
191
192} // namespace internal
193
[email protected]58580352010-10-26 04:07:50194} // namespace debug
195} // namespace base
196
197#endif // BASE_DEBUG_STACK_TRACE_H_