什么是coredump?
Coredump是继承于UNIX系统的机制,它用于保存程序出错而崩溃时的栈,内存,PID,UID,GID,时间等等信息的快照,通常用于程序诊断和调试,Coredump的信息在计算机中一般保存三天左右(依系统设定而定),如果出错的程序BUG不及时查找,超过三天系统会吧这些Coredump删除。
需要些什么工具?
一般来说,只需要objdump和gdb即可,诊断时源代码以原始为佳(core dumped时的未修改的代码)。
案例分析
下面是我展示的一个出错事例,供参考观摩。
程序崩溃了
这个程序运行时,一点问题也没有,就是退出时有小概率的情况出现崩溃,这种最让人头疼,像这种隐蔽BUG,很多情形不会触发它,却在某个特殊条件下,它突然就发生了。总结为两难:
- 难确定(是否发生)
- 难定位
见下图:

尝试用coredumpctl工具直接调试
coredumpctl是systemd的工具之一,只要用的是这个系统服务的,应该都有,此工具使用非常简单,可以命令输入以获帮助:
1 | coredumpctl --help |
或者,也可以查看它的man文档。
好了,言归正传,尝试输入命令以调试:
1 | coredumpctl debug xxxx |
上面的xxxx是程序文件名,关于该程序名,可以用
coredumpctl list
查看到
出现如下图的结果:

这种情况就比较复杂了,可以看见0x00007f77be94cf25 in ?? ()
这句,Coredump也不能在源代码确定具体出错的位置了,作为比较,我展示另一个例子:

上图这个例子出错代码立马被Coredump断定出来,很显然执行这句代码时崩溃的:
1 | *a = 0; |
这句是我故意改错用于比较的,源代码是这样的:
1 | bool input(string& filename, ...) { |
好了,我们继续前面的0x00007f77be94cf25 in ?? ()
这句,我们不能像前面这个立马断定,那该怎么办呢?
用coredumctl info
查看栈信息
下面两张图展示了这个崩溃程序的栈信息。
图一:

图二:
因为输出信息较宽,被我分成了两张图,注意图二中栈的调用列表,下面我们接着反汇编原始程序文件。
反汇编程序文件
反汇编原始崩溃程序文件时,不要忘记加--source
参数,不然全是汇编代码查找效率就不是很高,即输入命令带反汇编:
1 | objdump --source -d xxxx | less |
图片展示:

同样,xxxx为程序文件名
这时,我们可以在less
中依次查找各个栈地址(见图二所述),转到那个从libc
刚出来,在程序文件最先出错位置,即:0x42ce8
的文件位置,错误立马被锁定位置(可以依次查找栈上面的地址,顺藤摸瓜,可以断定那是在给list
进行clear
操作),原来是C++的类析构函数在析构一个list
时出的错误,继而判定这个错误实际上是个多线程引起的错误,因为程序中还有一个子线程也在释放操作,是主线程和子线程同时释放引起,对于释放资源,主/子线程没有加同步,从而导致时而正常,时而出错,加上一个最简单的同步机制,问题解决。