一、概述
C++程序崩溃时会产生core dump,一般有Segmentation Fault和Abort等。
二、保存core dump文件
很多时候需要保存core dump文件,方便后面调试修复BUG。
默认linux系统的core dump可能没有打开,因为core dump的文件很大,如果一个机器多个角色复用瞬间写很大的一个core dump文件,会大量占用机器资源,所以如果需要保存core dump文件我们得在运行前设置:
ulimit -c unlimited
此时,core文件会保存在当前目录下,并且只对当前终端有效。想要永久生效可以修改下系统配置,百度下就知道。
三、利用core文件定位、调试问题
core dump文件生成后,使用gdb调试定位问题。运行如下命令:
gdb 可执行程序 core
在gdb下可使用如下辅助命令方便快速定位问题:
bt 打印堆栈信息
bt
切换到出问题到frame:
f 20
打印此frame的变量的值
p xxx
四、动态库的core dump调试
如果是自己开发的动态库发生了core,调试时就会发现加载的so没有调试信息,也就没法定位问题了。
此时需要生成debug版的so才能在core dump调试时进行错误定位。
对于cmake编译的可以在CMakeList.txt中加入如下信息使之生成debug版的so:
add_definitions(-D_DEBUG)
add_definitions(-DDEBUG)
add_definitions("$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
五、崩溃监控方案
通过向系统注册发生Segmentation Fault和Abort时的回调即可监控C++的崩溃:
#include <signal.h> // ::signal
::signal(SIGSEGV, &my_signal_handler);
::signal(SIGABRT, &my_signal_handler);
在回调里就可采集崩溃栈等信息,可以使用boost库方便的记录backtrace等信息:
#include <signal.h> // ::signal, ::raise
#include <boost/stacktrace.hpp>
void my_signal_handler(int signum) {
::signal(signum, SIG_DFL);
boost::stacktrace::safe_dump_to("./backtrace.dump");
::raise(SIGABRT);
}
详细的可以参考boost官方参考:
http://boostorg.github.io/stacktrace/stacktrace/getting_started.html#stacktrace.getting_started.how_to_print_current_call_stack