summaryrefslogtreecommitdiff
path: root/absl/debugging/stacktrace.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2018-05-14 13:41:38 -0700
committerGravatar jueminyang <jueminyang@google.com>2018-05-15 11:00:30 -0400
commit04dd99d8c1813ded74cd2a9c90ecb7eaa2d68ab1 (patch)
treebcbac48462be4c3d39c1dcf933b55ea98f3928e8 /absl/debugging/stacktrace.h
parentadd89fd0e4bfd7d874bb55b67f4e13bf8beca762 (diff)
- abe587c2360b21f085b7d65a77d840015bc04cf6 Factor an internal interface into its own header, as it w... by Greg Falcon <gfalcon@google.com>
- 2201f1644336e64280dbd20207d8fbc3bfea2bf4 Internal change. by Abseil Team <absl-team@google.com> - 94e6b5b20d2cc754c99a18c575a4f1f3cd1f28d4 Rename no_throw_ctor to nothrow_ctor to match the standar... by Abseil Team <absl-team@google.com> - 86aa34d2129c4914c5133b7b619480aae786288e Update header files in debugging target by Tom Manshreck <shreck@google.com> - ed234519ced458724a7267b8fdf184eaae1c97c7 Remove CMAKE_CXX_WARNING_VLA from our c++ flags in the cm... by Jon Cohen <cohenjon@google.com> GitOrigin-RevId: abe587c2360b21f085b7d65a77d840015bc04cf6 Change-Id: I92f9301c69419d3830c358b88984967185aa33f6
Diffstat (limited to 'absl/debugging/stacktrace.h')
-rw-r--r--absl/debugging/stacktrace.h178
1 files changed, 118 insertions, 60 deletions
diff --git a/absl/debugging/stacktrace.h b/absl/debugging/stacktrace.h
index 82da3f15..8b831e26 100644
--- a/absl/debugging/stacktrace.h
+++ b/absl/debugging/stacktrace.h
@@ -1,5 +1,4 @@
-//
-// Copyright 2017 The Abseil Authors.
+// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -13,26 +12,37 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-
-// Routines to extract the current stack trace. These functions are
-// thread-safe and async-signal-safe.
+// -----------------------------------------------------------------------------
+// File: stacktrace.h
+// -----------------------------------------------------------------------------
+//
+// This file contains routines to extract the current stack trace and associated
+// stack frames. These functions are thread-safe and async-signal-safe.
+//
// Note that stack trace functionality is platform dependent and requires
-// additional support from the compiler/build system in many cases. (That is,
-// this generally only works on platforms/builds that have been specifically
-// configured to support it.)
+// additional support from the compiler/build system in most cases. (That is,
+// this functionality generally only works on platforms/builds that have been
+// specifically configured to support it.)
+//
+// Note: stack traces in Abseil that do not utilize a symbolizer will result in
+// frames consisting of function addresses rather than human-readable function
+// names. (See symbolize.h for information on symbolizing these values.)
#ifndef ABSL_DEBUGGING_STACKTRACE_H_
#define ABSL_DEBUGGING_STACKTRACE_H_
namespace absl {
-// Skips the most recent "skip_count" stack frames (also skips the
-// frame generated for the "absl::GetStackFrames" routine itself), and then
-// records the pc values for up to the next "max_depth" frames in
-// "result", and the corresponding stack frame sizes in "sizes".
-// Returns the number of values recorded in "result"/"sizes".
+// GetStackFrames()
+//
+// Records program counter values for up to `max_depth` frames, skipping the
+// most recent `skip_count` stack frames, and stores their corresponding values
+// and sizes in `results` and `sizes` buffers. (Note that the frame generated
+// for the `absl::GetStackFrames()` routine itself is also skipped.)
+// routine itself.
//
// Example:
+//
// main() { foo(); }
// foo() { bar(); }
// bar() {
@@ -41,41 +51,66 @@ namespace absl {
// int depth = absl::GetStackFrames(result, sizes, 10, 1);
// }
//
-// The absl::GetStackFrames call will skip the frame for "bar". It will
-// return 2 and will produce pc values that map to the following
-// procedures:
-// result[0] foo
-// result[1] main
-// (Actually, there may be a few more entries after "main" to account for
-// startup procedures.)
-// And corresponding stack frame sizes will also be recorded:
+// The current stack frame would consist of three function calls: `bar()`,
+// `foo()`, and then `main()`; however, since the `GetStackFrames()` call sets
+// `skip_count` to `1`, it will skip the frame for `bar()`, the most recently
+// invoked function call. It will therefore return two program counters and will
+// produce values that map to the following function calls:
+//
+// result[0] foo()
+// result[1] main()
+//
+// (Note: in practice, a few more entries after `main()` may be added to account
+// for startup processes.)
+//
+// Corresponding stack frame sizes will also be recorded:
+//
// sizes[0] 16
// sizes[1] 16
-// (Stack frame sizes of 16 above are just for illustration purposes.)
+//
+// (Stack frame sizes of `16` above are just for illustration purposes.)
+//
// Stack frame sizes of 0 or less indicate that those frame sizes couldn't
// be identified.
//
// This routine may return fewer stack frame entries than are
-// available. Also note that "result" and "sizes" must both be non-null.
+// available. Also note that `result` and `sizes` must both be non-null.
extern int GetStackFrames(void** result, int* sizes, int max_depth,
int skip_count);
-// Same as above, but to be used from a signal handler. The "uc" parameter
-// should be the pointer to ucontext_t which was passed as the 3rd parameter
-// to sa_sigaction signal handler. It may help the unwinder to get a
-// better stack trace under certain conditions. The "uc" may safely be null.
-//
-// If min_dropped_frames is not null, stores in *min_dropped_frames a
-// lower bound on the number of dropped stack frames. The stored value is
-// guaranteed to be >= 0. The number of real stack frames is guaranteed to
-// be >= skip_count + max_depth + *min_dropped_frames.
+// GetStackFramesWithContext()
+//
+// Records program counter values obtained from a signal handler. Records
+// program counter values for up to `max_depth` frames, skipping the most recent
+// `skip_count` stack frames, and stores their corresponding values and sizes in
+// `results` and `sizes` buffers. (Note that the frame generated for the
+// `absl::GetStackFramesWithContext()` routine itself is also skipped.)
+//
+// The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value
+// passed to a signal handler registered via the `sa_sigaction` field of a
+// `sigaction` struct. (See
+// http://man7.org/linux/man-pages/man2/sigaction.2.html.) The `uc` value may
+// help a stack unwinder to provide a better stack trace under certain
+// conditions. `uc` may safely be null.
+//
+// The `min_dropped_frames` output parameter, if non-null, points to the
+// location to note any dropped stack frames, if any, due to buffer limitations
+// or other reasons. (This value will be set to `0` if no frames were dropped.)
+// The number of total stack frames is guaranteed to be >= skip_count +
+// max_depth + *min_dropped_frames.
extern int GetStackFramesWithContext(void** result, int* sizes, int max_depth,
int skip_count, const void* uc,
int* min_dropped_frames);
-// This is similar to the absl::GetStackFrames routine, except that it returns
-// the stack trace only, and not the stack frame sizes as well.
+// GetStackTrace()
+//
+// Records program counter values for up to `max_depth` frames, skipping the
+// most recent `skip_count` stack frames, and stores their corresponding values
+// in `results`. Note that this function is similar to `absl::GetStackFrames()`
+// except that it returns the stack trace only, and not stack frame sizes.
+//
// Example:
+//
// main() { foo(); }
// foo() { bar(); }
// bar() {
@@ -84,42 +119,57 @@ extern int GetStackFramesWithContext(void** result, int* sizes, int max_depth,
// }
//
// This produces:
+//
// result[0] foo
// result[1] main
// .... ...
//
-// "result" must not be null.
+// `result` must not be null.
extern int GetStackTrace(void** result, int max_depth, int skip_count);
-// Same as above, but to be used from a signal handler. The "uc" parameter
-// should be the pointer to ucontext_t which was passed as the 3rd parameter
-// to sa_sigaction signal handler. It may help the unwinder to get a
-// better stack trace under certain conditions. The "uc" may safely be null.
-//
-// If min_dropped_frames is not null, stores in *min_dropped_frames a
-// lower bound on the number of dropped stack frames. The stored value is
-// guaranteed to be >= 0. The number of real stack frames is guaranteed to
-// be >= skip_count + max_depth + *min_dropped_frames.
+// GetStackTraceWithContext()
+//
+// Records program counter values obtained from a signal handler. Records
+// program counter values for up to `max_depth` frames, skipping the most recent
+// `skip_count` stack frames, and stores their corresponding values in
+// `results`. (Note that the frame generated for the
+// `absl::GetStackFramesWithContext()` routine itself is also skipped.)
+//
+// The `uc` parameter, if non-null, should be a pointer to a `ucontext_t` value
+// passed to a signal handler registered via the `sa_sigaction` field of a
+// `sigaction` struct. (See
+// http://man7.org/linux/man-pages/man2/sigaction.2.html.) The `uc` value may
+// help a stack unwinder to provide a better stack trace under certain
+// conditions. `uc` may safely be null.
+//
+// The `min_dropped_frames` output parameter, if non-null, points to the
+// location to note any dropped stack frames, if any, due to buffer limitations
+// or other reasons. (This value will be set to `0` if no frames were dropped.)
+// The number of total stack frames is guaranteed to be >= skip_count +
+// max_depth + *min_dropped_frames.
extern int GetStackTraceWithContext(void** result, int max_depth,
int skip_count, const void* uc,
int* min_dropped_frames);
-// Call this to provide a custom function for unwinding stack frames
-// that will be used every time someone invokes one of the static
+// SetStackUnwinder()
+//
+// Provides a custom function for unwinding stack frames that will be used in
+// place of the default stack unwinder when invoking the static
// GetStack{Frames,Trace}{,WithContext}() functions above.
//
// The arguments passed to the unwinder function will match the
-// arguments passed to absl::GetStackFramesWithContext() except that sizes
+// arguments passed to `absl::GetStackFramesWithContext()` except that sizes
// will be non-null iff the caller is interested in frame sizes.
//
-// If unwinder is null, we revert to the default stack-tracing behavior.
+// If unwinder is set to null, we revert to the default stack-tracing behavior.
//
-// ****************************************************************
-// WARNINGS
+// *****************************************************************************
+// WARNING
+// *****************************************************************************
//
// absl::SetStackUnwinder is not suitable for general purpose use. It is
// provided for custom runtimes.
-// Some things to watch out for when calling absl::SetStackUnwinder:
+// Some things to watch out for when calling `absl::SetStackUnwinder()`:
//
// (a) The unwinder may be called from within signal handlers and
// therefore must be async-signal-safe.
@@ -128,23 +178,31 @@ extern int GetStackTraceWithContext(void** result, int max_depth,
// threads may still be in the process of using that unwinder.
// Therefore do not clean up any state that may be needed by an old
// unwinder.
-// ****************************************************************
+// *****************************************************************************
extern void SetStackUnwinder(int (*unwinder)(void** pcs, int* sizes,
int max_depth, int skip_count,
const void* uc,
int* min_dropped_frames));
-// Function that exposes built-in stack-unwinding behavior, ignoring
-// any calls to absl::SetStackUnwinder().
+// DefaultStackUnwinder()
+//
+// Records program counter values of up to `max_depth` frames, skipping the most
+// recent `skip_count` stack frames, and stores their corresponding values in
+// `pcs`. (Note that the frame generated for this call itself is also skipped.)
+// This function acts as a generic stack-unwinder; prefer usage of the more
+// specific `GetStack{Trace,Frames}{,WithContext}()` functions above.
//
-// pcs must NOT be null.
+// If you have set your own stack unwinder (with the `SetStackUnwinder()`
+// function above, you can still get the default stack unwinder by calling
+// `DefaultStackUnwinder()`, which will ignore any previously set stack unwinder
+// and use the default one instead.
//
-// sizes may be null.
-// uc may be null.
-// min_dropped_frames may be null.
+// Because this function is generic, only `pcs` is guaranteed to be non-null
+// upon return. It is legal for `sizes`, `uc`, and `min_dropped_frames` to all
+// be null when called.
//
-// The semantics are the same as the corresponding GetStack*() function in the
-// case where absl::SetStackUnwinder() was never called. Equivalents are:
+// The semantics are the same as the corresponding `GetStack*()` function in the
+// case where `absl::SetStackUnwinder()` was never called. Equivalents are:
//
// null sizes | non-nullptr sizes
// |==========================================================|