stacktrace.h (12869B)
1 // Copyright 2018 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // ----------------------------------------------------------------------------- 16 // File: stacktrace.h 17 // ----------------------------------------------------------------------------- 18 // 19 // This file contains routines to extract the current stack trace and associated 20 // stack frames. These functions are thread-safe and async-signal-safe. 21 // 22 // Note that stack trace functionality is platform dependent and requires 23 // additional support from the compiler/build system in most cases. (That is, 24 // this functionality generally only works on platforms/builds that have been 25 // specifically configured to support it.) 26 // 27 // Note: stack traces in Abseil that do not utilize a symbolizer will result in 28 // frames consisting of function addresses rather than human-readable function 29 // names. (See symbolize.h for information on symbolizing these values.) 30 31 #ifndef ABSL_DEBUGGING_STACKTRACE_H_ 32 #define ABSL_DEBUGGING_STACKTRACE_H_ 33 34 #include <stdint.h> 35 36 #include "absl/base/attributes.h" 37 #include "absl/base/config.h" 38 39 namespace absl { 40 ABSL_NAMESPACE_BEGIN 41 42 namespace internal_stacktrace { 43 44 // Same as `absl::GetStackFrames`, but with an optional `frames` parameter to 45 // allow callers to receive the raw stack frame addresses. 46 // This is internal for now; use `absl::GetStackFrames()` instead. 47 extern int GetStackFrames(void** result, uintptr_t* frames, int* sizes, 48 int max_depth, int skip_count); 49 50 // Same as `absl::GetStackFramesWithContext`, but with an optional `frames` 51 // parameter to allow callers to receive a start address for each stack frame. 52 // The address may be zero in cases where it cannot be computed. 53 // 54 // DO NOT use this function without consulting the owners of absl/debuggging. 55 // There is NO GUARANTEE on the precise frame addresses returned on any given 56 // platform. It is only intended to provide sufficient non-overlapping bounds on 57 // the local variables of a stack frame when used in conjunction with the 58 // returned frame sizes. The actual pointers may be ABI-dependent, may vary at 59 // run time, and are subject to breakage without notice. 60 // 61 // Implementation note: 62 // Currently, we *attempt* to return the Canonical Frame Address (CFA) in DWARF 63 // on most platforms. This is the value of the stack pointer just before the 64 // 'call' instruction is executed in the caller. 65 // Not all platforms and toolchains support this exact address, so this should 66 // not be relied on for correctness. 67 extern int GetStackFramesWithContext(void** result, uintptr_t* frames, 68 int* sizes, int max_depth, int skip_count, 69 const void* uc, int* min_dropped_frames); 70 71 // Same as `absl::DefaultStackUnwinder`, but with an optional `frames` parameter 72 // to allow callers to receive the raw stack frame addresses. 73 // This is internal for now; do not depend on this externally. 74 extern int DefaultStackUnwinder(void** pcs, uintptr_t* frames, int* sizes, 75 int max_depth, int skip_count, const void* uc, 76 int* min_dropped_frames); 77 78 } // namespace internal_stacktrace 79 80 // GetStackFrames() 81 // 82 // Records program counter values for up to `max_depth` frames, skipping the 83 // most recent `skip_count` stack frames, stores their corresponding values 84 // and sizes in `results` and `sizes` buffers, and returns the number of frames 85 // stored. (Note that the frame generated for the `absl::GetStackFrames()` 86 // routine itself is also skipped.) 87 // 88 // Example: 89 // 90 // main() { foo(); } 91 // foo() { bar(); } 92 // bar() { 93 // void* result[10]; 94 // int sizes[10]; 95 // int depth = absl::GetStackFrames(result, sizes, 10, 1); 96 // } 97 // 98 // The current stack frame would consist of three function calls: `bar()`, 99 // `foo()`, and then `main()`; however, since the `GetStackFrames()` call sets 100 // `skip_count` to `1`, it will skip the frame for `bar()`, the most recently 101 // invoked function call. It will therefore return 2 and fill `result` with 102 // program counters within the following functions: 103 // 104 // result[0] foo() 105 // result[1] main() 106 // 107 // (Note: in practice, a few more entries after `main()` may be added to account 108 // for startup processes.) 109 // 110 // Corresponding stack frame sizes will also be recorded: 111 // 112 // sizes[0] 16 113 // sizes[1] 16 114 // 115 // (Stack frame sizes of `16` above are just for illustration purposes.) 116 // 117 // Stack frame sizes of 0 or less indicate that those frame sizes couldn't 118 // be identified. 119 // 120 // This routine may return fewer stack frame entries than are 121 // available. Also note that `result` and `sizes` must both be non-null. 122 ABSL_ATTRIBUTE_ALWAYS_INLINE inline int GetStackFrames(void** result, 123 int* sizes, 124 int max_depth, 125 int skip_count) { 126 return internal_stacktrace::GetStackFrames(result, nullptr, sizes, max_depth, 127 skip_count); 128 } 129 130 // GetStackFramesWithContext() 131 // 132 // Records program counter values obtained from a signal handler. Records 133 // program counter values for up to `max_depth` frames, skipping the most recent 134 // `skip_count` stack frames, stores their corresponding values and sizes in 135 // `results` and `sizes` buffers, and returns the number of frames stored. (Note 136 // that the frame generated for the `absl::GetStackFramesWithContext()` routine 137 // itself is also skipped.) 138 // 139 // The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value 140 // passed to a signal handler registered via the `sa_sigaction` field of a 141 // `sigaction` struct. (See 142 // http://man7.org/linux/man-pages/man2/sigaction.2.html.) The `uc` value may 143 // help a stack unwinder to provide a better stack trace under certain 144 // conditions. `uc` may safely be null. 145 // 146 // The `min_dropped_frames` output parameter, if non-null, points to the 147 // location to note any dropped stack frames, if any, due to buffer limitations 148 // or other reasons. (This value will be set to `0` if no frames were dropped.) 149 // The number of total stack frames is guaranteed to be >= skip_count + 150 // max_depth + *min_dropped_frames. 151 ABSL_ATTRIBUTE_ALWAYS_INLINE inline int GetStackFramesWithContext( 152 void** result, int* sizes, int max_depth, int skip_count, const void* uc, 153 int* min_dropped_frames) { 154 return internal_stacktrace::GetStackFramesWithContext( 155 result, nullptr, sizes, max_depth, skip_count, uc, min_dropped_frames); 156 } 157 158 // GetStackTrace() 159 // 160 // Records program counter values for up to `max_depth` frames, skipping the 161 // most recent `skip_count` stack frames, stores their corresponding values 162 // in `results`, and returns the number of frames 163 // stored. Note that this function is similar to `absl::GetStackFrames()` 164 // except that it returns the stack trace only, and not stack frame sizes. 165 // 166 // Example: 167 // 168 // main() { foo(); } 169 // foo() { bar(); } 170 // bar() { 171 // void* result[10]; 172 // int depth = absl::GetStackTrace(result, 10, 1); 173 // } 174 // 175 // This produces: 176 // 177 // result[0] foo 178 // result[1] main 179 // .... ... 180 // 181 // `result` must not be null. 182 extern int GetStackTrace(void** result, int max_depth, int skip_count); 183 184 // GetStackTraceWithContext() 185 // 186 // Records program counter values obtained from a signal handler. Records 187 // program counter values for up to `max_depth` frames, skipping the most recent 188 // `skip_count` stack frames, stores their corresponding values in `results`, 189 // and returns the number of frames stored. (Note that the frame generated for 190 // the `absl::GetStackFramesWithContext()` routine itself is also skipped.) 191 // 192 // The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value 193 // passed to a signal handler registered via the `sa_sigaction` field of a 194 // `sigaction` struct. (See 195 // http://man7.org/linux/man-pages/man2/sigaction.2.html.) The `uc` value may 196 // help a stack unwinder to provide a better stack trace under certain 197 // conditions. `uc` may safely be null. 198 // 199 // The `min_dropped_frames` output parameter, if non-null, points to the 200 // location to note any dropped stack frames, if any, due to buffer limitations 201 // or other reasons. (This value will be set to `0` if no frames were dropped.) 202 // The number of total stack frames is guaranteed to be >= skip_count + 203 // max_depth + *min_dropped_frames. 204 extern int GetStackTraceWithContext(void** result, int max_depth, 205 int skip_count, const void* uc, 206 int* min_dropped_frames); 207 208 // SetStackUnwinder() 209 // 210 // Provides a custom function for unwinding stack frames that will be used in 211 // place of the default stack unwinder when invoking the static 212 // GetStack{Frames,Trace}{,WithContext}() functions above. 213 // 214 // The arguments passed to the unwinder function will match the 215 // arguments passed to `absl::GetStackFramesWithContext()` except that sizes 216 // will be non-null iff the caller is interested in frame sizes. 217 // 218 // If unwinder is set to null, we revert to the default stack-tracing behavior. 219 // 220 // ***************************************************************************** 221 // WARNING 222 // ***************************************************************************** 223 // 224 // absl::SetStackUnwinder is not suitable for general purpose use. It is 225 // provided for custom runtimes. 226 // Some things to watch out for when calling `absl::SetStackUnwinder()`: 227 // 228 // (a) The unwinder may be called from within signal handlers and 229 // therefore must be async-signal-safe. 230 // 231 // (b) Even after a custom stack unwinder has been unregistered, other 232 // threads may still be in the process of using that unwinder. 233 // Therefore do not clean up any state that may be needed by an old 234 // unwinder. 235 // ***************************************************************************** 236 extern void SetStackUnwinder(int (*unwinder)(void** pcs, int* sizes, 237 int max_depth, int skip_count, 238 const void* uc, 239 int* min_dropped_frames)); 240 241 // DefaultStackUnwinder() 242 // 243 // Records program counter values of up to `max_depth` frames, skipping the most 244 // recent `skip_count` stack frames, and stores their corresponding values in 245 // `pcs`. (Note that the frame generated for this call itself is also skipped.) 246 // This function acts as a generic stack-unwinder; prefer usage of the more 247 // specific `GetStack{Trace,Frames}{,WithContext}()` functions above. 248 // 249 // If you have set your own stack unwinder (with the `SetStackUnwinder()` 250 // function above, you can still get the default stack unwinder by calling 251 // `DefaultStackUnwinder()`, which will ignore any previously set stack unwinder 252 // and use the default one instead. 253 // 254 // Because this function is generic, only `pcs` is guaranteed to be non-null 255 // upon return. It is legal for `sizes`, `uc`, and `min_dropped_frames` to all 256 // be null when called. 257 // 258 // The semantics are the same as the corresponding `GetStack*()` function in the 259 // case where `absl::SetStackUnwinder()` was never called. Equivalents are: 260 // 261 // null sizes | non-nullptr sizes 262 // |==========================================================| 263 // null uc | GetStackTrace() | GetStackFrames() | 264 // non-null uc | GetStackTraceWithContext() | GetStackFramesWithContext() | 265 // |==========================================================| 266 extern int DefaultStackUnwinder(void** pcs, int* sizes, int max_depth, 267 int skip_count, const void* uc, 268 int* min_dropped_frames); 269 270 namespace debugging_internal { 271 // Returns true for platforms which are expected to have functioning stack trace 272 // implementations. Intended to be used for tests which want to exclude 273 // verification of logic known to be broken because stack traces are not 274 // working. 275 extern bool StackTraceWorksForTest(); 276 } // namespace debugging_internal 277 ABSL_NAMESPACE_END 278 } // namespace absl 279 280 #endif // ABSL_DEBUGGING_STACKTRACE_H_