mirror of
https://https.git.savannah.gnu.org/git/gnulib.git
synced 2026-06-15 15:25:49 +00:00
77 lines
3.2 KiB
Plaintext
77 lines
3.2 KiB
Plaintext
@node Stack traces
|
|
@section Stack traces
|
|
|
|
@c Copyright (C) 2024--2026 Free Software Foundation, Inc.
|
|
|
|
@c Permission is granted to copy, distribute and/or modify this document
|
|
@c under the terms of the GNU Free Documentation License, Version 1.3 or
|
|
@c any later version published by the Free Software Foundation; with no
|
|
@c Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
|
|
@c copy of the license is at <https://www.gnu.org/licenses/fdl-1.3.en.html>.
|
|
|
|
@c Written by Bruno Haible.
|
|
|
|
@mindex stack-trace
|
|
|
|
Printing a stack trace
|
|
was traditionally seen as a feature of the debugging environment
|
|
and thus only implemented in the debuggers (@command{gdb} etc.).
|
|
However, they are also useful in production code,
|
|
for use in two circumstances:
|
|
@itemize
|
|
@item
|
|
When a problem occurs on a user's machine,
|
|
when the user is merely a user, not a programmer.
|
|
@item
|
|
In unit tests that run in continuous-integration environments.
|
|
In such environments, the virtual machine is discarded
|
|
immediately after the tests have run.
|
|
It is not possible to run a debugger in such environments.
|
|
@end itemize
|
|
@noindent
|
|
And in fact, printing a stack trace is part of the basic runtime system
|
|
in programming languages such as
|
|
Java (@url{https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#printStackTrace--, printStackTrace method}),
|
|
Python (@url{https://docs.python.org/3/library/traceback.html, print_exception method}),
|
|
Go (@url{https://pkg.go.dev/runtime/debug#PrintStack, PrintStack function}),
|
|
and
|
|
ISO C++ 23 (@url{https://en.cppreference.com/w/cpp/utility/basic_stacktrace, std::stacktrace class}).
|
|
|
|
Gnulib provides a module @samp{stack-trace} with this feature:
|
|
@code{print_stack_trace ()}
|
|
prints a stack trace of the current thread to standard error.
|
|
|
|
For it to work best, three requirements need to be met:
|
|
@itemize
|
|
@item
|
|
The @url{https://github.com/ianlancetaylor/libbacktrace, libbacktrace library}
|
|
or GCC's sanitizer library @code{libasan} needs to be installed.
|
|
@item
|
|
The program needs to be compiled with debugging information (option @code{-g}).
|
|
@item
|
|
On macOS, where debugging information
|
|
is stored in a separate directory rather than in the compiled binary
|
|
(see @url{https://stackoverflow.com/questions/10044697/#12827463}),
|
|
the @code{dsymutil} program needs to be used when linking,
|
|
and the debugging information needs to be copied when the program is installed.
|
|
Cf. @url{https://github.com/ianlancetaylor/libbacktrace/issues/122#issuecomment-2122589147}.
|
|
@end itemize
|
|
|
|
When these requirements are not met, the function @code{print_stack_trace ()}
|
|
either prints a stack trace without source file names and line numbers,
|
|
or prints nothing at all.
|
|
|
|
@mindex abort-debug
|
|
Gnulib also provides a module @samp{abort-debug},
|
|
that overrides the @code{abort} function so that
|
|
it prints the stack trace of the current thread, before actually aborting.
|
|
Thus, @code{abort ()} remains the idiom of choice
|
|
for signaling a fatal situation that requires developer attention:
|
|
it is useful both in debugging environments and production code.
|
|
|
|
Note:
|
|
While the original @code{abort} function is safe to call in signal handlers,
|
|
the overridden @code{abort} function is not.
|
|
In signal handlers, you will need to call the original @code{abort} function,
|
|
by doing @code{#undef abort} first.
|