coredump
简单来说,core dump说的是操作系统执行的一个动作,当某个进程因为一些原因意外终止(crash)的时候,操作系统会将这个进程当时的内存信息转储(dump)到磁盘上1。产生的文件就是core文件了,一般会以core.xxx形式命名。
如何产生Core Dump
一般来说, 当进程接收到某个信号导致进程退出或crash(崩溃)的时候, 会产生一个 core dump 文件.
比如经常遇到的数组越界或者访问空指针都会产生一个SIGSEGV型号, 导致程序崩溃, 这个时候就会产生一个core dump.
以下是默认产生 coredump 的一些信号.
3)SIGQUIT 4)SIGILL6)SIGABRT 8)SIGFPE 11)SIGSEGV 7)SIGBUS31)SIGSYS
5)SIGTRAP 24)SIGXCPU25)SIGXFSZ 29)SIGIOT
需要注意的是当程序自己接管了信号处理后不会产生core dump了.
Core Dump 设置
以上只是产生coredump的必要条件,而非充分条件。要产生core文件还依赖于程序运行的shell,可以通过ulimit -c命令查看core file size设置. 这个值用来限制产生的 core 文件大小, 超过这个值就不会保存了. 如果设置为0,就是不会保存core文件. 即使产生了, 也不会保存. 可以使用 ulimit-c unlimited 将core dump打开.
默认情况下,产生的 core dump 文件名为 core. 可以通过设置内核参数
/proc/sys/kernel/core_pattern设置产生 core 文件的模板.
以下是参数列表:
%p - 文件名添加pid
%u - 文件名添加当前uid
%g - 文件名添加当前gid
%s - 文件名添加导致产生core的信号
%t - 文件名添加core文件生成时的unix时间
%h - 文件名添加主机名
%e - 文件名添加执行文件名
如果 /proc/sys/kernel/core_pattern 模板不包含 "%p" 且
/proc/sys/kernel/core_uses_pid 为非0, 则当前 pid 将添加到 core 文件命.
gdb 调试 core dump
创建一个空指针的crash.c
int crash(void *in)
{
uint8_t *ptr = NULL;
*ptr = 0x1;
return 0;
}
int main(int argc,char **argv)
{
crash(NULL);
return 0;
}
~
root@ubuntu:/work/Code#gcc -g crash.c -o crash
gcc -g参数很重要,可以产生调试 symbol直接定位错误文件, 函数,代码行.
root@ubuntu:/work/Code#./crash
Segmentationfault (core dumped)
产生core dump 文件.
root@ubuntu:/work/Code#gdb crash core
Readingsymbols from /work/Code/crash...done.
[New Thread2294]
warning: Can'tread pathname for load map: Input/output error.
Readingsymbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbolsfor /lib/libc.so.6
Readingsymbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbolsfor /lib64/ld-linux-x86-64.so.2
Core wasgenerated by `./crash'.
Programterminated with signal 11, Segmentation fault.
#0 0x00000000004004d8 in crash (in=0x0) atcrash.c:14
14 *ptr = 0x1;
(gdb)
此刻已马上定位到crash.c 14 行.
也调用 gdbwhere/backtrace 查看当前的函数调用栈的所有信息.
(gdb) where
#0 0x00000000004004d8 in crash (in=0x0) atcrash.c:14
#1 0x00000000004004fb in main (argc=1,argv=0x7fffdb7f6998) at crash.c:20
(gdb)backtrace
#0 0x00000000004004d8 in crash (in=0x0) atcrash.c:14
#1 0x00000000004004fb in main (argc=1,argv=0x7fffdb7f6998) at crash.c:20
(gdb)
(gdb) thread apply[thread no]/[all] command 可调试多线程 .
(gdb) thread applyall bt
显示所有线程的调用栈信息
可以参考系统core详细说明 :
man core