|
|
|||
File indexing completed on 2025-12-16 09:40:50
0001 // Copyright 2018 The Abseil Authors. 0002 // 0003 // Licensed under the Apache License, Version 2.0 (the "License"); 0004 // you may not use this file except in compliance with the License. 0005 // You may obtain a copy of the License at 0006 // 0007 // https://www.apache.org/licenses/LICENSE-2.0 0008 // 0009 // Unless required by applicable law or agreed to in writing, software 0010 // distributed under the License is distributed on an "AS IS" BASIS, 0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0012 // See the License for the specific language governing permissions and 0013 // limitations under the License. 0014 // 0015 // ----------------------------------------------------------------------------- 0016 // File: stacktrace.h 0017 // ----------------------------------------------------------------------------- 0018 // 0019 // This file contains routines to extract the current stack trace and associated 0020 // stack frames. These functions are thread-safe and async-signal-safe. 0021 // 0022 // Note that stack trace functionality is platform dependent and requires 0023 // additional support from the compiler/build system in most cases. (That is, 0024 // this functionality generally only works on platforms/builds that have been 0025 // specifically configured to support it.) 0026 // 0027 // Note: stack traces in Abseil that do not utilize a symbolizer will result in 0028 // frames consisting of function addresses rather than human-readable function 0029 // names. (See symbolize.h for information on symbolizing these values.) 0030 0031 #ifndef ABSL_DEBUGGING_STACKTRACE_H_ 0032 #define ABSL_DEBUGGING_STACKTRACE_H_ 0033 0034 #include "absl/base/config.h" 0035 0036 namespace absl { 0037 ABSL_NAMESPACE_BEGIN 0038 0039 // GetStackFrames() 0040 // 0041 // Records program counter values for up to `max_depth` frames, skipping the 0042 // most recent `skip_count` stack frames, stores their corresponding values 0043 // and sizes in `results` and `sizes` buffers, and returns the number of frames 0044 // stored. (Note that the frame generated for the `absl::GetStackFrames()` 0045 // routine itself is also skipped.) 0046 // 0047 // Example: 0048 // 0049 // main() { foo(); } 0050 // foo() { bar(); } 0051 // bar() { 0052 // void* result[10]; 0053 // int sizes[10]; 0054 // int depth = absl::GetStackFrames(result, sizes, 10, 1); 0055 // } 0056 // 0057 // The current stack frame would consist of three function calls: `bar()`, 0058 // `foo()`, and then `main()`; however, since the `GetStackFrames()` call sets 0059 // `skip_count` to `1`, it will skip the frame for `bar()`, the most recently 0060 // invoked function call. It will therefore return 2 and fill `result` with 0061 // program counters within the following functions: 0062 // 0063 // result[0] foo() 0064 // result[1] main() 0065 // 0066 // (Note: in practice, a few more entries after `main()` may be added to account 0067 // for startup processes.) 0068 // 0069 // Corresponding stack frame sizes will also be recorded: 0070 // 0071 // sizes[0] 16 0072 // sizes[1] 16 0073 // 0074 // (Stack frame sizes of `16` above are just for illustration purposes.) 0075 // 0076 // Stack frame sizes of 0 or less indicate that those frame sizes couldn't 0077 // be identified. 0078 // 0079 // This routine may return fewer stack frame entries than are 0080 // available. Also note that `result` and `sizes` must both be non-null. 0081 extern int GetStackFrames(void** result, int* sizes, int max_depth, 0082 int skip_count); 0083 0084 // GetStackFramesWithContext() 0085 // 0086 // Records program counter values obtained from a signal handler. Records 0087 // program counter values for up to `max_depth` frames, skipping the most recent 0088 // `skip_count` stack frames, stores their corresponding values and sizes in 0089 // `results` and `sizes` buffers, and returns the number of frames stored. (Note 0090 // that the frame generated for the `absl::GetStackFramesWithContext()` routine 0091 // itself is also skipped.) 0092 // 0093 // The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value 0094 // passed to a signal handler registered via the `sa_sigaction` field of a 0095 // `sigaction` struct. (See 0096 // http://man7.org/linux/man-pages/man2/sigaction.2.html.) The `uc` value may 0097 // help a stack unwinder to provide a better stack trace under certain 0098 // conditions. `uc` may safely be null. 0099 // 0100 // The `min_dropped_frames` output parameter, if non-null, points to the 0101 // location to note any dropped stack frames, if any, due to buffer limitations 0102 // or other reasons. (This value will be set to `0` if no frames were dropped.) 0103 // The number of total stack frames is guaranteed to be >= skip_count + 0104 // max_depth + *min_dropped_frames. 0105 extern int GetStackFramesWithContext(void** result, int* sizes, int max_depth, 0106 int skip_count, const void* uc, 0107 int* min_dropped_frames); 0108 0109 // GetStackTrace() 0110 // 0111 // Records program counter values for up to `max_depth` frames, skipping the 0112 // most recent `skip_count` stack frames, stores their corresponding values 0113 // in `results`, and returns the number of frames 0114 // stored. Note that this function is similar to `absl::GetStackFrames()` 0115 // except that it returns the stack trace only, and not stack frame sizes. 0116 // 0117 // Example: 0118 // 0119 // main() { foo(); } 0120 // foo() { bar(); } 0121 // bar() { 0122 // void* result[10]; 0123 // int depth = absl::GetStackTrace(result, 10, 1); 0124 // } 0125 // 0126 // This produces: 0127 // 0128 // result[0] foo 0129 // result[1] main 0130 // .... ... 0131 // 0132 // `result` must not be null. 0133 extern int GetStackTrace(void** result, int max_depth, int skip_count); 0134 0135 // GetStackTraceWithContext() 0136 // 0137 // Records program counter values obtained from a signal handler. Records 0138 // program counter values for up to `max_depth` frames, skipping the most recent 0139 // `skip_count` stack frames, stores their corresponding values in `results`, 0140 // and returns the number of frames stored. (Note that the frame generated for 0141 // the `absl::GetStackFramesWithContext()` routine itself is also skipped.) 0142 // 0143 // The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value 0144 // passed to a signal handler registered via the `sa_sigaction` field of a 0145 // `sigaction` struct. (See 0146 // http://man7.org/linux/man-pages/man2/sigaction.2.html.) The `uc` value may 0147 // help a stack unwinder to provide a better stack trace under certain 0148 // conditions. `uc` may safely be null. 0149 // 0150 // The `min_dropped_frames` output parameter, if non-null, points to the 0151 // location to note any dropped stack frames, if any, due to buffer limitations 0152 // or other reasons. (This value will be set to `0` if no frames were dropped.) 0153 // The number of total stack frames is guaranteed to be >= skip_count + 0154 // max_depth + *min_dropped_frames. 0155 extern int GetStackTraceWithContext(void** result, int max_depth, 0156 int skip_count, const void* uc, 0157 int* min_dropped_frames); 0158 0159 // SetStackUnwinder() 0160 // 0161 // Provides a custom function for unwinding stack frames that will be used in 0162 // place of the default stack unwinder when invoking the static 0163 // GetStack{Frames,Trace}{,WithContext}() functions above. 0164 // 0165 // The arguments passed to the unwinder function will match the 0166 // arguments passed to `absl::GetStackFramesWithContext()` except that sizes 0167 // will be non-null iff the caller is interested in frame sizes. 0168 // 0169 // If unwinder is set to null, we revert to the default stack-tracing behavior. 0170 // 0171 // ***************************************************************************** 0172 // WARNING 0173 // ***************************************************************************** 0174 // 0175 // absl::SetStackUnwinder is not suitable for general purpose use. It is 0176 // provided for custom runtimes. 0177 // Some things to watch out for when calling `absl::SetStackUnwinder()`: 0178 // 0179 // (a) The unwinder may be called from within signal handlers and 0180 // therefore must be async-signal-safe. 0181 // 0182 // (b) Even after a custom stack unwinder has been unregistered, other 0183 // threads may still be in the process of using that unwinder. 0184 // Therefore do not clean up any state that may be needed by an old 0185 // unwinder. 0186 // ***************************************************************************** 0187 extern void SetStackUnwinder(int (*unwinder)(void** pcs, int* sizes, 0188 int max_depth, int skip_count, 0189 const void* uc, 0190 int* min_dropped_frames)); 0191 0192 // DefaultStackUnwinder() 0193 // 0194 // Records program counter values of up to `max_depth` frames, skipping the most 0195 // recent `skip_count` stack frames, and stores their corresponding values in 0196 // `pcs`. (Note that the frame generated for this call itself is also skipped.) 0197 // This function acts as a generic stack-unwinder; prefer usage of the more 0198 // specific `GetStack{Trace,Frames}{,WithContext}()` functions above. 0199 // 0200 // If you have set your own stack unwinder (with the `SetStackUnwinder()` 0201 // function above, you can still get the default stack unwinder by calling 0202 // `DefaultStackUnwinder()`, which will ignore any previously set stack unwinder 0203 // and use the default one instead. 0204 // 0205 // Because this function is generic, only `pcs` is guaranteed to be non-null 0206 // upon return. It is legal for `sizes`, `uc`, and `min_dropped_frames` to all 0207 // be null when called. 0208 // 0209 // The semantics are the same as the corresponding `GetStack*()` function in the 0210 // case where `absl::SetStackUnwinder()` was never called. Equivalents are: 0211 // 0212 // null sizes | non-nullptr sizes 0213 // |==========================================================| 0214 // null uc | GetStackTrace() | GetStackFrames() | 0215 // non-null uc | GetStackTraceWithContext() | GetStackFramesWithContext() | 0216 // |==========================================================| 0217 extern int DefaultStackUnwinder(void** pcs, int* sizes, int max_depth, 0218 int skip_count, const void* uc, 0219 int* min_dropped_frames); 0220 0221 namespace debugging_internal { 0222 // Returns true for platforms which are expected to have functioning stack trace 0223 // implementations. Intended to be used for tests which want to exclude 0224 // verification of logic known to be broken because stack traces are not 0225 // working. 0226 extern bool StackTraceWorksForTest(); 0227 } // namespace debugging_internal 0228 ABSL_NAMESPACE_END 0229 } // namespace absl 0230 0231 #endif // ABSL_DEBUGGING_STACKTRACE_H_
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|