blob: 5796f560d374c240f1d8026a96e08b30b8c9a7fd [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
erikchend6b2b822017-02-22 21:10:3141// Returns end of the stack, or 0 if we couldn't get it.
erikchenf7c8a0d2017-04-06 21:15:2742#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
erikchend6b2b822017-02-22 21:10:3143BASE_EXPORT uintptr_t GetStackEnd();
44#endif
45
[email protected]58580352010-10-26 04:07:5046// A stacktrace can be helpful in debugging. For example, you can include a
47// stacktrace member in a object (probably around #ifndef NDEBUG) so that you
48// can later see where the given object was created from.
[email protected]0bea7252011-08-05 15:34:0049class BASE_EXPORT StackTrace {
[email protected]58580352010-10-26 04:07:5050 public:
51 // Creates a stacktrace from the current location.
52 StackTrace();
53
wez73f8d7e2017-01-29 06:18:1354 // Creates a stacktrace from the current location, of up to |count| entries.
55 // |count| will be limited to at most |kMaxTraces|.
56 explicit StackTrace(size_t count);
57
[email protected]f01ae9812011-08-30 19:33:0458 // Creates a stacktrace from an existing array of instruction
59 // pointers (such as returned by Addresses()). |count| will be
wez73f8d7e2017-01-29 06:18:1360 // limited to at most |kMaxTraces|.
[email protected]f01ae9812011-08-30 19:33:0461 StackTrace(const void* const* trace, size_t count);
62
[email protected]58580352010-10-26 04:07:5063#if defined(OS_WIN)
64 // Creates a stacktrace for an exception.
65 // Note: this function will throw an import not found (StackWalk64) exception
66 // on system without dbghelp 5.1.
jam79dc59a2015-08-17 03:38:1667 StackTrace(_EXCEPTION_POINTERS* exception_pointers);
rnk0565cdd62015-10-06 16:48:3068 StackTrace(const _CONTEXT* context);
[email protected]58580352010-10-26 04:07:5069#endif
70
71 // Copying and assignment are allowed with the default functions.
72
[email protected]58580352010-10-26 04:07:5073 // Gets an array of instruction pointer values. |*count| will be set to the
74 // number of elements in the returned array.
[email protected]501dfc42011-04-14 16:34:0075 const void* const* Addresses(size_t* count) const;
[email protected]58580352010-10-26 04:07:5076
[email protected]5ddbf1c2013-08-29 01:59:3877 // Prints the stack trace to stderr.
78 void Print() const;
[email protected]58580352010-10-26 04:07:5079
[email protected]7cf10ed2014-06-27 09:21:0380#if !defined(__UCLIBC__)
[email protected]58580352010-10-26 04:07:5081 // Resolves backtrace to symbols and write to stream.
[email protected]501dfc42011-04-14 16:34:0082 void OutputToStream(std::ostream* os) const;
[email protected]816e50452014-04-09 22:29:3883#endif
[email protected]58580352010-10-26 04:07:5084
[email protected]d4114ba2011-10-12 16:13:4085 // Resolves backtrace to symbols and returns as string.
86 std::string ToString() const;
87
[email protected]58580352010-10-26 04:07:5088 private:
wittman7808da72015-02-03 17:46:5189#if defined(OS_WIN)
rnk0565cdd62015-10-06 16:48:3090 void InitTrace(const _CONTEXT* context_record);
wittman7808da72015-02-03 17:46:5191#endif
92
[email protected]58580352010-10-26 04:07:5093 // From http://msdn.microsoft.com/en-us/library/bb204633.aspx,
94 // the sum of FramesToSkip and FramesToCapture must be less than 63,
95 // so set it to 62. Even if on POSIX it could be a larger value, it usually
96 // doesn't give much more information.
97 static const int kMaxTraces = 62;
98
99 void* trace_[kMaxTraces];
[email protected]e645c7a2012-07-25 21:43:44100
101 // The number of valid frames in |trace_|.
102 size_t count_;
[email protected]58580352010-10-26 04:07:50103};
104
erikchenf7c8a0d2017-04-06 21:15:27105#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
dskiba79080da02016-04-23 00:10:27106// Traces the stack by using frame pointers. This function is faster but less
107// reliable than StackTrace. It should work for debug and profiling builds,
108// but not for release builds (although there are some exceptions).
109//
110// Writes at most |max_depth| frames (instruction pointers) into |out_trace|
111// after skipping |skip_initial| frames. Note that the function itself is not
112// added to the trace so |skip_initial| should be 0 in most cases.
113// Returns number of frames written.
114BASE_EXPORT size_t TraceStackFramePointers(const void** out_trace,
115 size_t max_depth,
116 size_t skip_initial);
dskibaa8c951e2016-10-25 23:39:11117
wez3731f7d22017-03-30 06:22:51118#if !defined(OS_WIN)
dskibaa8c951e2016-10-25 23:39:11119// Links stack frame |fp| to |parent_fp|, so that during stack unwinding
120// TraceStackFramePointers() visits |parent_fp| after visiting |fp|.
121// Both frame pointers must come from __builtin_frame_address().
122// Destructor restores original linkage of |fp| to avoid corrupting caller's
123// frame register on return.
124//
125// This class can be used to repair broken stack frame chain in cases
126// when execution flow goes into code built without frame pointers:
127//
128// void DoWork() {
129// Call_SomeLibrary();
130// }
131// static __thread void* g_saved_fp;
132// void Call_SomeLibrary() {
133// g_saved_fp = __builtin_frame_address(0);
134// some_library_call(...); // indirectly calls SomeLibrary_Callback()
135// }
136// void SomeLibrary_Callback() {
137// ScopedStackFrameLinker linker(__builtin_frame_address(0), g_saved_fp);
138// ...
139// TraceStackFramePointers(...);
140// }
141//
142// This produces the following trace:
143//
144// #0 SomeLibrary_Callback()
145// #1 <address of the code inside SomeLibrary that called #0>
146// #2 DoWork()
147// ...rest of the trace...
148//
149// SomeLibrary doesn't use frame pointers, so when SomeLibrary_Callback()
150// is called, stack frame register contains bogus value that becomes callback'
151// parent frame address. Without ScopedStackFrameLinker unwinding would've
152// stopped at that bogus frame address yielding just two first frames (#0, #1).
153// ScopedStackFrameLinker overwrites callback's parent frame address with
154// Call_SomeLibrary's frame, so unwinder produces full trace without even
155// noticing that stack frame chain was broken.
156class BASE_EXPORT ScopedStackFrameLinker {
157 public:
158 ScopedStackFrameLinker(void* fp, void* parent_fp);
159 ~ScopedStackFrameLinker();
160
161 private:
162 void* fp_;
163 void* parent_fp_;
164 void* original_parent_fp_;
165
166 DISALLOW_COPY_AND_ASSIGN(ScopedStackFrameLinker);
167};
wez3731f7d22017-03-30 06:22:51168#endif // !defined(OS_WIN)
dskibaa8c951e2016-10-25 23:39:11169
erikchenf7c8a0d2017-04-06 21:15:27170#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
dskiba79080da02016-04-23 00:10:27171
[email protected]1e218b72012-11-14 19:32:23172namespace internal {
173
174#if defined(OS_POSIX) && !defined(OS_ANDROID)
175// POSIX doesn't define any async-signal safe function for converting
176// an integer to ASCII. We'll have to define our own version.
177// itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the
178// conversion was successful or NULL otherwise. It never writes more than "sz"
179// bytes. Output will be truncated as needed, and a NUL character is always
180// appended.
[email protected]22d5b9822013-01-10 18:21:52181BASE_EXPORT char *itoa_r(intptr_t i,
182 char *buf,
183 size_t sz,
184 int base,
185 size_t padding);
[email protected]1e218b72012-11-14 19:32:23186#endif // defined(OS_POSIX) && !defined(OS_ANDROID)
187
188} // namespace internal
189
[email protected]58580352010-10-26 04:07:50190} // namespace debug
191} // namespace base
192
193#endif // BASE_DEBUG_STACK_TRACE_H_