简体   繁体   English

在 Linux 上的发布/优化二进制文件中的信号处理程序中打印回溯

[英]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.例如,我们可以使用backtracebacktrace_symbolsabi::__cxa_demangle来打印堆栈跟踪。 But as far as I know we need to build the binaries with compiler flags -g , and not above -O1 optimization flags.但据我所知,我们需要使用编译器标志-g构建二进制文件,而不是高于-O1优化标志。 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.我期待在发布二进制文件中生成具有正确函数名称的回溯,例如使用-O3标志编译。

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?更新 1:有没有办法让我们可以有一个包含一些符号的辅助文件,并且可以引用它从优化的二进制过程中生成堆栈跟踪?

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.无论优化级别如何,在信号处理程序中调用backtrace 1backtrace_symbols 1abi::__cxa_demangle 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).关于打印,如果您计划使用任何printf系列函数,请知道在信号处理程序中使用它们也不安全(至少是 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. 1,根据手册页,使用backtrace应该是OK,只要共享libgcc中已预先加载。 backtrace_symbols has a safer alternative backtrace_symbols_fd , which has the same caveat with libgcc. backtrace_symbols有一个更安全的替代backtrace_symbols_fd ,它与 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 .您可以使用objcopy从可执行文件中复制调试符号,并使用strip从可执行文件中strip

GDB supports external symbol files, but I don't know if / how they can be used from within the program. GDB 支持外部符号文件,但我不知道是否/如何在程序中使用它们。 I've used SymtabAPI to dig symbols out of binaries;我使用SymtabAPI从二进制文件中挖掘符号; 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.无需担心信号安全,生成trace时无需延迟原进程重启,无需额外依赖服务端进程。


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.就优化级别而言,无论您使用什么方法来生成跟踪,您都可以尝试-O3 -fno-omit-frame-pointer并希望获得最佳效果,但通常最好不要使用高于-O2的调试。 -Og is ideal, but not as fast. -Og是理想的,但没有那么快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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