00001 // Copyright 2018 The Abseil Authors. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // https://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 // 00015 // ----------------------------------------------------------------------------- 00016 // File: stacktrace.h 00017 // ----------------------------------------------------------------------------- 00018 // 00019 // This file contains routines to extract the current stack trace and associated 00020 // stack frames. These functions are thread-safe and async-signal-safe. 00021 // 00022 // Note that stack trace functionality is platform dependent and requires 00023 // additional support from the compiler/build system in most cases. (That is, 00024 // this functionality generally only works on platforms/builds that have been 00025 // specifically configured to support it.) 00026 // 00027 // Note: stack traces in Abseil that do not utilize a symbolizer will result in 00028 // frames consisting of function addresses rather than human-readable function 00029 // names. (See symbolize.h for information on symbolizing these values.) 00030 00031 #ifndef ABSL_DEBUGGING_STACKTRACE_H_ 00032 #define ABSL_DEBUGGING_STACKTRACE_H_ 00033 00034 namespace absl { 00035 00036 // GetStackFrames() 00037 // 00038 // Records program counter values for up to `max_depth` frames, skipping the 00039 // most recent `skip_count` stack frames, and stores their corresponding values 00040 // and sizes in `results` and `sizes` buffers. (Note that the frame generated 00041 // for the `absl::GetStackFrames()` routine itself is also skipped.) 00042 // routine itself. 00043 // 00044 // Example: 00045 // 00046 // main() { foo(); } 00047 // foo() { bar(); } 00048 // bar() { 00049 // void* result[10]; 00050 // int sizes[10]; 00051 // int depth = absl::GetStackFrames(result, sizes, 10, 1); 00052 // } 00053 // 00054 // The current stack frame would consist of three function calls: `bar()`, 00055 // `foo()`, and then `main()`; however, since the `GetStackFrames()` call sets 00056 // `skip_count` to `1`, it will skip the frame for `bar()`, the most recently 00057 // invoked function call. It will therefore return two program counters and will 00058 // produce values that map to the following function calls: 00059 // 00060 // result[0] foo() 00061 // result[1] main() 00062 // 00063 // (Note: in practice, a few more entries after `main()` may be added to account 00064 // for startup processes.) 00065 // 00066 // Corresponding stack frame sizes will also be recorded: 00067 // 00068 // sizes[0] 16 00069 // sizes[1] 16 00070 // 00071 // (Stack frame sizes of `16` above are just for illustration purposes.) 00072 // 00073 // Stack frame sizes of 0 or less indicate that those frame sizes couldn't 00074 // be identified. 00075 // 00076 // This routine may return fewer stack frame entries than are 00077 // available. Also note that `result` and `sizes` must both be non-null. 00078 extern int GetStackFrames(void** result, int* sizes, int max_depth, 00079 int skip_count); 00080 00081 // GetStackFramesWithContext() 00082 // 00083 // Records program counter values obtained from a signal handler. Records 00084 // program counter values for up to `max_depth` frames, skipping the most recent 00085 // `skip_count` stack frames, and stores their corresponding values and sizes in 00086 // `results` and `sizes` buffers. (Note that the frame generated for the 00087 // `absl::GetStackFramesWithContext()` routine itself is also skipped.) 00088 // 00089 // The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value 00090 // passed to a signal handler registered via the `sa_sigaction` field of a 00091 // `sigaction` struct. (See 00092 // http://man7.org/linux/man-pages/man2/sigaction.2.html.) The `uc` value may 00093 // help a stack unwinder to provide a better stack trace under certain 00094 // conditions. `uc` may safely be null. 00095 // 00096 // The `min_dropped_frames` output parameter, if non-null, points to the 00097 // location to note any dropped stack frames, if any, due to buffer limitations 00098 // or other reasons. (This value will be set to `0` if no frames were dropped.) 00099 // The number of total stack frames is guaranteed to be >= skip_count + 00100 // max_depth + *min_dropped_frames. 00101 extern int GetStackFramesWithContext(void** result, int* sizes, int max_depth, 00102 int skip_count, const void* uc, 00103 int* min_dropped_frames); 00104 00105 // GetStackTrace() 00106 // 00107 // Records program counter values for up to `max_depth` frames, skipping the 00108 // most recent `skip_count` stack frames, and stores their corresponding values 00109 // in `results`. Note that this function is similar to `absl::GetStackFrames()` 00110 // except that it returns the stack trace only, and not stack frame sizes. 00111 // 00112 // Example: 00113 // 00114 // main() { foo(); } 00115 // foo() { bar(); } 00116 // bar() { 00117 // void* result[10]; 00118 // int depth = absl::GetStackTrace(result, 10, 1); 00119 // } 00120 // 00121 // This produces: 00122 // 00123 // result[0] foo 00124 // result[1] main 00125 // .... ... 00126 // 00127 // `result` must not be null. 00128 extern int GetStackTrace(void** result, int max_depth, int skip_count); 00129 00130 // GetStackTraceWithContext() 00131 // 00132 // Records program counter values obtained from a signal handler. Records 00133 // program counter values for up to `max_depth` frames, skipping the most recent 00134 // `skip_count` stack frames, and stores their corresponding values in 00135 // `results`. (Note that the frame generated for the 00136 // `absl::GetStackFramesWithContext()` routine itself is also skipped.) 00137 // 00138 // The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value 00139 // passed to a signal handler registered via the `sa_sigaction` field of a 00140 // `sigaction` struct. (See 00141 // http://man7.org/linux/man-pages/man2/sigaction.2.html.) The `uc` value may 00142 // help a stack unwinder to provide a better stack trace under certain 00143 // conditions. `uc` may safely be null. 00144 // 00145 // The `min_dropped_frames` output parameter, if non-null, points to the 00146 // location to note any dropped stack frames, if any, due to buffer limitations 00147 // or other reasons. (This value will be set to `0` if no frames were dropped.) 00148 // The number of total stack frames is guaranteed to be >= skip_count + 00149 // max_depth + *min_dropped_frames. 00150 extern int GetStackTraceWithContext(void** result, int max_depth, 00151 int skip_count, const void* uc, 00152 int* min_dropped_frames); 00153 00154 // SetStackUnwinder() 00155 // 00156 // Provides a custom function for unwinding stack frames that will be used in 00157 // place of the default stack unwinder when invoking the static 00158 // GetStack{Frames,Trace}{,WithContext}() functions above. 00159 // 00160 // The arguments passed to the unwinder function will match the 00161 // arguments passed to `absl::GetStackFramesWithContext()` except that sizes 00162 // will be non-null iff the caller is interested in frame sizes. 00163 // 00164 // If unwinder is set to null, we revert to the default stack-tracing behavior. 00165 // 00166 // ***************************************************************************** 00167 // WARNING 00168 // ***************************************************************************** 00169 // 00170 // absl::SetStackUnwinder is not suitable for general purpose use. It is 00171 // provided for custom runtimes. 00172 // Some things to watch out for when calling `absl::SetStackUnwinder()`: 00173 // 00174 // (a) The unwinder may be called from within signal handlers and 00175 // therefore must be async-signal-safe. 00176 // 00177 // (b) Even after a custom stack unwinder has been unregistered, other 00178 // threads may still be in the process of using that unwinder. 00179 // Therefore do not clean up any state that may be needed by an old 00180 // unwinder. 00181 // ***************************************************************************** 00182 extern void SetStackUnwinder(int (*unwinder)(void** pcs, int* sizes, 00183 int max_depth, int skip_count, 00184 const void* uc, 00185 int* min_dropped_frames)); 00186 00187 // DefaultStackUnwinder() 00188 // 00189 // Records program counter values of up to `max_depth` frames, skipping the most 00190 // recent `skip_count` stack frames, and stores their corresponding values in 00191 // `pcs`. (Note that the frame generated for this call itself is also skipped.) 00192 // This function acts as a generic stack-unwinder; prefer usage of the more 00193 // specific `GetStack{Trace,Frames}{,WithContext}()` functions above. 00194 // 00195 // If you have set your own stack unwinder (with the `SetStackUnwinder()` 00196 // function above, you can still get the default stack unwinder by calling 00197 // `DefaultStackUnwinder()`, which will ignore any previously set stack unwinder 00198 // and use the default one instead. 00199 // 00200 // Because this function is generic, only `pcs` is guaranteed to be non-null 00201 // upon return. It is legal for `sizes`, `uc`, and `min_dropped_frames` to all 00202 // be null when called. 00203 // 00204 // The semantics are the same as the corresponding `GetStack*()` function in the 00205 // case where `absl::SetStackUnwinder()` was never called. Equivalents are: 00206 // 00207 // null sizes | non-nullptr sizes 00208 // |==========================================================| 00209 // null uc | GetStackTrace() | GetStackFrames() | 00210 // non-null uc | GetStackTraceWithContext() | GetStackFramesWithContext() | 00211 // |==========================================================| 00212 extern int DefaultStackUnwinder(void** pcs, int* sizes, int max_depth, 00213 int skip_count, const void* uc, 00214 int* min_dropped_frames); 00215 00216 namespace debugging_internal { 00217 // Returns true for platforms which are expected to have functioning stack trace 00218 // implementations. Intended to be used for tests which want to exclude 00219 // verification of logic known to be broken because stack traces are not 00220 // working. 00221 extern bool StackTraceWorksForTest(); 00222 } // namespace debugging_internal 00223 } // namespace absl 00224 00225 #endif // ABSL_DEBUGGING_STACKTRACE_H_