blob: 0e4b91dadf1844bb68292d8c635fba4de3091911 [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"
Scott Violet44165792018-02-22 02:08:0814#include "base/debug/debugging_buildflags.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
Mason Freedb9ef2b62018-09-10 17:17:2786 // Prints the stack trace to stderr, prepending the given string before
87 // each output line.
88 void PrintWithPrefix(const char* prefix_string) const;
89
rayb0088ee52017-04-26 22:35:0890#if !defined(__UCLIBC__) & !defined(_AIX)
[email protected]58580352010-10-26 04:07:5091 // Resolves backtrace to symbols and write to stream.
[email protected]501dfc42011-04-14 16:34:0092 void OutputToStream(std::ostream* os) const;
Mason Freedb9ef2b62018-09-10 17:17:2793 // Resolves backtrace to symbols and write to stream, with the provided
94 // prefix string prepended to each line.
95 void OutputToStreamWithPrefix(std::ostream* os,
96 const char* prefix_string) const;
[email protected]816e50452014-04-09 22:29:3897#endif
[email protected]58580352010-10-26 04:07:5098
[email protected]d4114ba2011-10-12 16:13:4099 // Resolves backtrace to symbols and returns as string.
100 std::string ToString() const;
101
Mason Freedb9ef2b62018-09-10 17:17:27102 // Resolves backtrace to symbols and returns as string, prepending the
103 // provided prefix string to each line.
104 std::string ToStringWithPrefix(const char* prefix_string) const;
105
[email protected]58580352010-10-26 04:07:50106 private:
wittman7808da72015-02-03 17:46:51107#if defined(OS_WIN)
rnk0565cdd62015-10-06 16:48:30108 void InitTrace(const _CONTEXT* context_record);
wittman7808da72015-02-03 17:46:51109#endif
110
[email protected]58580352010-10-26 04:07:50111 // From http://msdn.microsoft.com/en-us/library/bb204633.aspx,
112 // the sum of FramesToSkip and FramesToCapture must be less than 63,
113 // so set it to 62. Even if on POSIX it could be a larger value, it usually
114 // doesn't give much more information.
115 static const int kMaxTraces = 62;
116
117 void* trace_[kMaxTraces];
[email protected]e645c7a2012-07-25 21:43:44118
119 // The number of valid frames in |trace_|.
120 size_t count_;
[email protected]58580352010-10-26 04:07:50121};
122
erikchenf7c8a0d2017-04-06 21:15:27123#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
dskiba79080da02016-04-23 00:10:27124// Traces the stack by using frame pointers. This function is faster but less
125// reliable than StackTrace. It should work for debug and profiling builds,
126// but not for release builds (although there are some exceptions).
127//
128// Writes at most |max_depth| frames (instruction pointers) into |out_trace|
129// after skipping |skip_initial| frames. Note that the function itself is not
130// added to the trace so |skip_initial| should be 0 in most cases.
131// Returns number of frames written.
132BASE_EXPORT size_t TraceStackFramePointers(const void** out_trace,
133 size_t max_depth,
134 size_t skip_initial);
dskibaa8c951e2016-10-25 23:39:11135
136// Links stack frame |fp| to |parent_fp|, so that during stack unwinding
137// TraceStackFramePointers() visits |parent_fp| after visiting |fp|.
138// Both frame pointers must come from __builtin_frame_address().
139// Destructor restores original linkage of |fp| to avoid corrupting caller's
140// frame register on return.
141//
142// This class can be used to repair broken stack frame chain in cases
143// when execution flow goes into code built without frame pointers:
144//
145// void DoWork() {
146// Call_SomeLibrary();
147// }
148// static __thread void* g_saved_fp;
149// void Call_SomeLibrary() {
150// g_saved_fp = __builtin_frame_address(0);
151// some_library_call(...); // indirectly calls SomeLibrary_Callback()
152// }
153// void SomeLibrary_Callback() {
154// ScopedStackFrameLinker linker(__builtin_frame_address(0), g_saved_fp);
155// ...
156// TraceStackFramePointers(...);
157// }
158//
159// This produces the following trace:
160//
161// #0 SomeLibrary_Callback()
162// #1 <address of the code inside SomeLibrary that called #0>
163// #2 DoWork()
164// ...rest of the trace...
165//
166// SomeLibrary doesn't use frame pointers, so when SomeLibrary_Callback()
167// is called, stack frame register contains bogus value that becomes callback'
168// parent frame address. Without ScopedStackFrameLinker unwinding would've
169// stopped at that bogus frame address yielding just two first frames (#0, #1).
170// ScopedStackFrameLinker overwrites callback's parent frame address with
171// Call_SomeLibrary's frame, so unwinder produces full trace without even
172// noticing that stack frame chain was broken.
173class BASE_EXPORT ScopedStackFrameLinker {
174 public:
175 ScopedStackFrameLinker(void* fp, void* parent_fp);
176 ~ScopedStackFrameLinker();
177
178 private:
179 void* fp_;
180 void* parent_fp_;
181 void* original_parent_fp_;
182
183 DISALLOW_COPY_AND_ASSIGN(ScopedStackFrameLinker);
184};
185
erikchenf7c8a0d2017-04-06 21:15:27186#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
dskiba79080da02016-04-23 00:10:27187
[email protected]1e218b72012-11-14 19:32:23188namespace internal {
189
190#if defined(OS_POSIX) && !defined(OS_ANDROID)
191// POSIX doesn't define any async-signal safe function for converting
192// an integer to ASCII. We'll have to define our own version.
193// itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the
194// conversion was successful or NULL otherwise. It never writes more than "sz"
195// bytes. Output will be truncated as needed, and a NUL character is always
196// appended.
[email protected]22d5b9822013-01-10 18:21:52197BASE_EXPORT char *itoa_r(intptr_t i,
198 char *buf,
199 size_t sz,
200 int base,
201 size_t padding);
[email protected]1e218b72012-11-14 19:32:23202#endif // defined(OS_POSIX) && !defined(OS_ANDROID)
203
204} // namespace internal
205
[email protected]58580352010-10-26 04:07:50206} // namespace debug
207} // namespace base
208
209#endif // BASE_DEBUG_STACK_TRACE_H_