Printing backtrace within signal handler
Regardless of optimisation level, it is not safe to call backtrace
1, backtrace_symbols
1, nor abi::__cxa_demangle
in a signal handler. They are not async-safe functions, and may cause the program to crash, corrupt memory or freeze if used within a signal handler. Regarding printing, in case you were planning to use any printf
family of functions, know that they are also not safe to use in a signal handler (at least all of the ones specified by POSIX).
There are libraries / functions that promise signal-safe stack unwinding, as well as demangling, formatting and output which make this possible.
1 According to man pages, using backtrace
should be OK as long as the shared libgcc has been loaded beforehand. backtrace_symbols
has a safer alternative backtrace_symbols_fd
, which has the same caveat with libgcc.
Is there a way that we can have a secondary file containing some symbols
You can copy the debug symbols from the executable using objcopy
and remove from the executable using strip
.
GDB supports external symbol files, but I don't know if / how they can be used from within the program. I've used SymtabAPI to dig symbols out of binaries; that might work with external symbol files as well. But that library does not promise signal safety as far as I know. That said, it's unclear why the separation would be needed; The debug symbols don't affect performance.
I am going to print the stack only if the process crashes
In this case, a possibly better approach might be to simply let the operating system generate a core dump, and have a separate process listening for file system events, and once a core dump is created, generate a back trace and write to some log. No worries about signal safety, no need to delay the original process from restarting while generating the trace, and no extra dependencies to the server process.
As far as the optimisation level goes, regardless of what method you use to generate the trace, you could try -O3 -fno-omit-frame-pointer
and hope for the best, but it's usually best not to use higher than -O2
for debugging. -Og
is ideal, but not as fast.