Yog*_*esh 4 c c++ stack-trace backtrace signal-handling
问题在于以编程方式在优化的二进制文件中打印有意义的stacktrace。例如,我们可以使用backtrace,backtrace_symbols,abi :: __ cxa_demangle打印堆栈跟踪。但据我所知,我们需要使用编译器标志-g而不是-O1优化标志来构建二进制文件。我可以做到的。
我期待在发行二进制文件(例如,用-03标志编译)中生成具有正确函数名称的回溯。
可行吗?我对此进行了大量研究,但没有任何实质性意义。
更新1:有没有一种方法可以让我们创建一个包含一些符号的辅助文件,并且可以在优化的二进制过程中引用该文件来生成堆栈跟踪?
在信号处理程序中打印回溯
不管优化级别的,它是不安全的通话backtrace1,backtrace_symbols1,也不abi::__cxa_demangle在信号处理程序。它们不是异步安全功能,如果在信号处理程序中使用,可能会导致程序崩溃,内存损坏或冻结。关于打印,如果您打算使用任何printf系列的功能,请知道在信号处理程序(至少是POSIX指定的所有功能)中使用它们也不安全。
有一些库/函数可以保证信号安全的堆栈展开,以及解包,格式化和输出,这使这成为可能。
1根据手册页,只要预先加载了共享libgcc ,使用backtrace 应该可以。backtrace_symbols有一个更安全的选择backtrace_symbols_fd,它与libgcc有相同的警告。
有没有办法让我们包含一些符号的辅助文件
您可以使用来从可执行文件复制调试符号,并使用来从可执行文件中objcopy删除调试符号strip。
GDB支持外部符号文件,但我不知道是否/如何在程序中使用它们。我已经使用SymtabAPI从二进制文件中提取符号。也可以与外部符号文件一起使用。但是据我所知,该库不能保证信号安全。也就是说,目前尚不清楚为什么需要分离。调试符号不会影响性能。
仅当进程崩溃时,我才打印堆栈
在这种情况下,可能更好的方法可能是简单地让操作系统生成核心转储,并让一个单独的进程侦听文件系统事件,一旦创建核心转储,就生成回溯并写入一些日志。无需担心信号安全性,无需在生成跟踪时延迟原始进程的重新启动,也无需依赖服务器进程。
就优化级别而言,无论您使用哪种方法生成跟踪,都可以尝试-O3 -fno-omit-frame-pointer并希望达到最佳效果,但是通常最好不要使用高于-O2调试的水平。-Og是理想的,但没有那么快。