diff options
Diffstat (limited to 'absl/debugging')
-rw-r--r-- | absl/debugging/failure_signal_handler.h | 110 |
1 files changed, 62 insertions, 48 deletions
diff --git a/absl/debugging/failure_signal_handler.h b/absl/debugging/failure_signal_handler.h index 17522f00b13f..c57954e5875c 100644 --- a/absl/debugging/failure_signal_handler.h +++ b/absl/debugging/failure_signal_handler.h @@ -1,4 +1,3 @@ -// // Copyright 2018 The Abseil Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,85 +12,100 @@ // See the License for the specific language governing permissions and // limitations under the License. // - -// This module allows the programmer to install a signal handler that -// dumps useful debugging information (like a stacktrace) on program -// failure. To use this functionality, call -// absl::InstallFailureSignalHandler() very early in your program, -// usually in the first few lines of main(): +// ----------------------------------------------------------------------------- +// File: failure_signal_handler.h +// ----------------------------------------------------------------------------- +// +// This file configures the Abseil *failure signal handler* to capture and dump +// useful debugging information (such as a stacktrace) upon program failure. +// +// To use the failure signal handler, call `absl::InstallFailureSignalHandler()` +// very early in your program, usually in the first few lines of main(): // // int main(int argc, char** argv) { +// // Initialize the symbolizer to get a human-readable stack trace // absl::InitializeSymbolizer(argv[0]); +// // absl::FailureSignalHandlerOptions options; // absl::InstallFailureSignalHandler(options); // DoSomethingInteresting(); // return 0; // } +// +// Any program that raises a fatal signal (such as `SIGSEGV`, `SIGILL`, +// `SIGFPE`, `SIGABRT`, `SIGTERM`, `SIGBUG`, and `SIGTRAP`) will call the +// installed failure signal handler and provide debugging information to stderr. +// +// Note that you should *not* install the Abseil failure signal handler more +// than once. You may, of course, have another (non-Abseil) failure signal +// handler installed (which would be triggered if Abseil's failure signal +// handler sets `call_previous_handler` to `true`). #ifndef ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ #define ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ namespace absl { -// Options struct for absl::InstallFailureSignalHandler(). +// FailureSignalHandlerOptions +// +// Struct for holding `absl::InstallFailureSignalHandler()` configuration +// options. struct FailureSignalHandlerOptions { - // If true, try to symbolize the stacktrace emitted on failure. + // If true, try to symbolize the stacktrace emitted on failure, provided that + // you have initialized a symbolizer for that purpose. (See symbolize.h for + // more information.) bool symbolize_stacktrace = true; - // If true, try to run signal handlers on an alternate stack (if - // supported on the given platform). This is useful in the case - // where the program crashes due to a stack overflow. By running on - // a alternate stack, the signal handler might be able to run even - // when the normal stack space has been exausted. The downside of - // using an alternate stack is that extra memory for the alternate - // stack needs to be pre-allocated. + // If true, try to run signal handlers on an alternate stack (if supported on + // the given platform). An alternate stack is useful for program crashes due + // to a stack overflow; by running on a alternate stack, the signal handler + // may run even when normal stack space has been exausted. The downside of + // using an alternate stack is that extra memory for the alternate stack needs + // to be pre-allocated. bool use_alternate_stack = true; - // If positive, FailureSignalHandler() sets an alarm to be delivered - // to the program after this many seconds, which will immediately - // abort the program. This is useful in the potential case where - // FailureSignalHandler() itself is hung or deadlocked. + // If positive, indicates the number of seconds after which the failure signal + // handler is invoked to abort the program. Setting such an alarm is useful in + // cases where the failure signal handler itself may become hung or + // deadlocked. int alarm_on_failure_secs = 3; - // If false, after absl::FailureSignalHandler() runs, the signal is - // raised to the default handler for that signal (which normally - // terminates the program). + // If true, call the previously registered signal handler for the signal that + // was received (if one was registered) after the existing signal handler + // runs. This mechanism can be used to chain signal handlers together. // - // If true, after absl::FailureSignalHandler() runs, it will call - // the previously registered signal handler for the signal that was - // received (if one was registered). This can be used to chain - // signal handlers. + // If false, the signal is raised to the default handler for that signal + // (which normally terminates the program). // - // IMPORTANT: If true, the chained fatal signal handlers must not - // try to recover from the fatal signal. Instead, they should - // terminate the program via some mechanism, like raising the - // default handler for the signal, or by calling _exit(). - // absl::FailureSignalHandler() may put parts of the Abseil - // library into a state that cannot be recovered from. + // IMPORTANT: If true, the chained fatal signal handlers must not try to + // recover from the fatal signal. Instead, they should terminate the program + // via some mechanism, like raising the default handler for the signal, or by + // calling `_exit()`. Note that the failure signal handler may put parts of + // the Abseil library into a state from which they cannot recover. bool call_previous_handler = false; - // If not null, this function may be called with a std::string argument - // containing failure data. This function is used as a hook to write - // the failure data to a secondary location, for instance, to a log - // file. This function may also be called with a null data - // argument. This is a hint that this is a good time to flush any - // buffered data before the program may be terminated. Consider + // If non-null, indicates a pointer to a callback function that will be called + // upon failure, with a std::string argument containing failure data. This function + // may be used as a hook to write failure data to a secondary location, such + // as a log file. This function may also be called with null data, as a hint + // to flush any buffered data before the program may be terminated. Consider // flushing any buffered data in all calls to this function. // - // Since this function runs in a signal handler, it should be + // Since this function runs within a signal handler, it should be // async-signal-safe if possible. // See http://man7.org/linux/man-pages/man7/signal-safety.7.html void (*writerfn)(const char*) = nullptr; }; -// Installs a signal handler for the common failure signals SIGSEGV, -// SIGILL, SIGFPE, SIGABRT, SIGTERM, SIGBUG, and SIGTRAP (if they -// exist on the given platform). The signal handler dumps program -// failure data in a unspecified format to stderr. The data dumped by -// the signal handler includes information that may be useful in -// debugging the failure. This may include the program counter, a -// stacktrace, and register information on some systems. Do not rely -// on the exact format of the output; it is subject to change. +// InstallFailureSignalHandler() +// +// Installs a signal handler for the common failure signals `SIGSEGV`, `SIGILL`, +// `SIGFPE`, `SIGABRT`, `SIGTERM`, `SIGBUG`, and `SIGTRAP` (provided they exist +// on the given platform). The failure signal handler dumps program failure data +// useful for debugging in an unspecified format to stderr. This data may +// include the program counter, a stacktrace, and register information on some +// systems; do not rely on an exact format for the output, as it is subject to +// change. void InstallFailureSignalHandler(const FailureSignalHandlerOptions& options); namespace debugging_internal { |