所谓的 core 其实就是 memory,早先的存储器十分昂贵,是用磁心器件做的用于保存临时数据, core dump 就是把运行出错时把进程的内存段像倒垃圾一样倾泻出来。现在的计算机就是倒腾到磁盘上,用于事后分析问题,最开始的计算机就是全部打印出来(反正总共可以用到的内存也不是很多)。于是可以想象一下当年码农的作业场景,一个长发胡子拉擦的人通过打孔机把指令交给计算机,然后兴奋的等待结果,忽然,红灯一闪,然后打印机里面开始疯狂的工作。接着,码农垂头丧气的拿着一卷 core dump 的结果回去分析去了。
空指针、野指针、非法指针,这些在c语言里面耳熟能详的名字往往是导致 core dump 的罪魁祸首。操作系统能够给你的内存总是有限的,你一越界他就不干了,立马终止程序运行,把你产生的垃圾还给你。
参考 stackoverflow 上面的这个问题,可以通过
cat /proc/sys/kernel/core_pattern
来查看自己的计算机是 core dump 到哪里了。
一般是在/var/cache/abrt,如果使用的是 systemd,那么 core dump 是记录到 systemd自己的日志里面,可以通过 systemd-coredumpctl 进行操作。比如
sudo systemd-coredumpctl list
就是用来列出所有 dump 的文件,然后可以同 gdb 调试。
在目录 /var/lib/systemd/coredump 里面可以找到
嵌入式系统里面,可以把这些信息重定向到串口输出,将当前的上下文,内存数据文本化,通过串口输出,然后使用特定工具解析,最后可以用 arm-gdb 分析,比如[CrashDebug][https://github.com/adamgreen/CrashDebug]
一般是用 objdump 查看 core dump 的文件,然后可以用万能的 gdb 进行调试。比如,我给 strlen 传递了一个空指针。通过
sudo systemd-coredumpctl gdb 3058
可以看到出错的信息
Program terminated with signal 11, Segmentation fault.
#0 0x00007fa595b56801 in __strlen_sse2_pminub ()
from /usr/lib/libc.so.6
这样就可以看到出错的“大概”位置。
调试近期的 coredump
coredumpctl gdb gvim