简体   繁体   中英

Printing backtrace within signal handler in a release/optimized binary on Linux

The question is about printing a meaningful stacktrace programmatically in optimized binary. eg We can use backtrace , backtrace_symbols , abi::__cxa_demangle to print a stack trace. But as far as I know we need to build the binaries with compiler flags -g , and not above -O1 optimization flags. I can achieve this.

I am looking forward to generate a backtrace with proper function names in a release binary eg compiled with -O3 flag.

Is it viable? I did quite a lot of research on this, but couldn't get anything substantial.

Update 1: Is there a way that we can have a secondary file containing some symbols and that can be referred to generate stack trace from within the optimized binary process?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM