blob: 82da3f15fa7d482137efdd67ced64a112a538a6e [file] [log] [blame]
mistergc2e75482017-09-19 16:54:40 -04001//
2// Copyright 2017 The Abseil Authors.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17// Routines to extract the current stack trace. These functions are
18// thread-safe and async-signal-safe.
19// Note that stack trace functionality is platform dependent and requires
20// additional support from the compiler/build system in many cases. (That is,
21// this generally only works on platforms/builds that have been specifically
22// configured to support it.)
23
24#ifndef ABSL_DEBUGGING_STACKTRACE_H_
25#define ABSL_DEBUGGING_STACKTRACE_H_
26
27namespace absl {
28
29// Skips the most recent "skip_count" stack frames (also skips the
30// frame generated for the "absl::GetStackFrames" routine itself), and then
31// records the pc values for up to the next "max_depth" frames in
32// "result", and the corresponding stack frame sizes in "sizes".
33// Returns the number of values recorded in "result"/"sizes".
34//
35// Example:
36// main() { foo(); }
37// foo() { bar(); }
38// bar() {
39// void* result[10];
40// int sizes[10];
41// int depth = absl::GetStackFrames(result, sizes, 10, 1);
42// }
43//
44// The absl::GetStackFrames call will skip the frame for "bar". It will
45// return 2 and will produce pc values that map to the following
46// procedures:
47// result[0] foo
48// result[1] main
49// (Actually, there may be a few more entries after "main" to account for
50// startup procedures.)
51// And corresponding stack frame sizes will also be recorded:
52// sizes[0] 16
53// sizes[1] 16
54// (Stack frame sizes of 16 above are just for illustration purposes.)
55// Stack frame sizes of 0 or less indicate that those frame sizes couldn't
56// be identified.
57//
58// This routine may return fewer stack frame entries than are
59// available. Also note that "result" and "sizes" must both be non-null.
60extern int GetStackFrames(void** result, int* sizes, int max_depth,
61 int skip_count);
62
63// Same as above, but to be used from a signal handler. The "uc" parameter
64// should be the pointer to ucontext_t which was passed as the 3rd parameter
65// to sa_sigaction signal handler. It may help the unwinder to get a
66// better stack trace under certain conditions. The "uc" may safely be null.
67//
68// If min_dropped_frames is not null, stores in *min_dropped_frames a
69// lower bound on the number of dropped stack frames. The stored value is
70// guaranteed to be >= 0. The number of real stack frames is guaranteed to
71// be >= skip_count + max_depth + *min_dropped_frames.
72extern int GetStackFramesWithContext(void** result, int* sizes, int max_depth,
73 int skip_count, const void* uc,
74 int* min_dropped_frames);
75
76// This is similar to the absl::GetStackFrames routine, except that it returns
77// the stack trace only, and not the stack frame sizes as well.
78// Example:
79// main() { foo(); }
80// foo() { bar(); }
81// bar() {
82// void* result[10];
83// int depth = absl::GetStackTrace(result, 10, 1);
84// }
85//
86// This produces:
87// result[0] foo
88// result[1] main
89// .... ...
90//
91// "result" must not be null.
92extern int GetStackTrace(void** result, int max_depth, int skip_count);
93
94// Same as above, but to be used from a signal handler. The "uc" parameter
95// should be the pointer to ucontext_t which was passed as the 3rd parameter
96// to sa_sigaction signal handler. It may help the unwinder to get a
97// better stack trace under certain conditions. The "uc" may safely be null.
98//
99// If min_dropped_frames is not null, stores in *min_dropped_frames a
100// lower bound on the number of dropped stack frames. The stored value is
101// guaranteed to be >= 0. The number of real stack frames is guaranteed to
102// be >= skip_count + max_depth + *min_dropped_frames.
103extern int GetStackTraceWithContext(void** result, int max_depth,
104 int skip_count, const void* uc,
105 int* min_dropped_frames);
106
107// Call this to provide a custom function for unwinding stack frames
108// that will be used every time someone invokes one of the static
109// GetStack{Frames,Trace}{,WithContext}() functions above.
110//
111// The arguments passed to the unwinder function will match the
112// arguments passed to absl::GetStackFramesWithContext() except that sizes
113// will be non-null iff the caller is interested in frame sizes.
114//
115// If unwinder is null, we revert to the default stack-tracing behavior.
116//
117// ****************************************************************
118// WARNINGS
119//
120// absl::SetStackUnwinder is not suitable for general purpose use. It is
121// provided for custom runtimes.
122// Some things to watch out for when calling absl::SetStackUnwinder:
123//
124// (a) The unwinder may be called from within signal handlers and
125// therefore must be async-signal-safe.
126//
127// (b) Even after a custom stack unwinder has been unregistered, other
128// threads may still be in the process of using that unwinder.
129// Therefore do not clean up any state that may be needed by an old
130// unwinder.
131// ****************************************************************
132extern void SetStackUnwinder(int (*unwinder)(void** pcs, int* sizes,
133 int max_depth, int skip_count,
134 const void* uc,
135 int* min_dropped_frames));
136
137// Function that exposes built-in stack-unwinding behavior, ignoring
138// any calls to absl::SetStackUnwinder().
139//
140// pcs must NOT be null.
141//
142// sizes may be null.
143// uc may be null.
144// min_dropped_frames may be null.
145//
146// The semantics are the same as the corresponding GetStack*() function in the
147// case where absl::SetStackUnwinder() was never called. Equivalents are:
148//
149// null sizes | non-nullptr sizes
150// |==========================================================|
151// null uc | GetStackTrace() | GetStackFrames() |
152// non-null uc | GetStackTraceWithContext() | GetStackFramesWithContext() |
153// |==========================================================|
154extern int DefaultStackUnwinder(void** pcs, int* sizes, int max_depth,
155 int skip_count, const void* uc,
156 int* min_dropped_frames);
157
Abseil Team5a8de8a2018-01-17 09:53:47 -0800158namespace debugging_internal {
159// Returns true for platforms which are expected to have functioning stack trace
160// implementations. Intended to be used for tests which want to exclude
161// verification of logic known to be broken because stack traces are not
162// working.
163extern bool StackTraceWorksForTest();
164} // namespace debugging_internal
mistergc2e75482017-09-19 16:54:40 -0400165} // namespace absl
166
167#endif // ABSL_DEBUGGING_STACKTRACE_H_