1 前言
当前生产环境下C++程序存在排错的问题,如果仅是业务异常导致出错,往往有日志可以提供详细信息,但如果是代码错误导致程序段错误崩溃,就没有太好的解决方法。
目前比较常见的方式有以下几种:
- 程序内部捕获段错误信号,当发生段错误时,打印backtrace信息
- 程序不捕获段错误信号,设置Coredump文件输出路径,将core文件导入开发环境排错
- 在2的基础上,生产环境同时部署
-g
的执行文件,当有core文件时使用debug
版现场定位问题。
其中,第一种方法虽然能大致定位代码逻辑错误位置,但由于没有足够的堆栈数据,很难正式确认问题;第二种方式操作较为复杂,同时存在生产数据泄露到开发环境的风险;第三种方式目前相对而言最优,但会导致编译构建时间翻倍,同时发布包体积翻倍的问题。
近期学到一种新方法,主要在方案3的基础上改进——使用objcopy
将符号导出。
2 objcopy将DEBUG符号摘出
objcopy
是GNU
工具集中的一个,作用是从一个二进制文件中拷贝特定信息到另一个文件中。
利用它我们可以将debug
版的程序中的符号表导出到程序外部,当需要调试的时候再将符号表导入二进制程序,进行调试。
在编译构建二进制目标时,需要编译选项增加-g
符号,用于将符号表导入,此时gdb
可以正常使用。
然后使用下面的命令对符号表进行导出、移除和放入:
2.1 示例
我们先准备一个稳定触发段错误的代码:
对应编译选项
这个时候我们可以编译运行,得到:
我们可以通过gdb来运行
接下来我们移除符号到cpp_test.dbg
,再gdb
运行:
发现找不到符号了。
但当我们再将符号表导入,则又正常了。
后续在生产上只需要设置core文件的文件名和路径即可:core-设置core文件名和路径并手动触发coredump