Back to home page

EIC code displayed by LXR

 
 

    


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_