coredump
简单来说,core dump说的是操作系统执行的一个动作,当某个进程因为一些原因意外终止(crash)的时候,操作系统会将这个进程当时的内存信息转储(dump)到磁盘上1。产生的文件就是core文件了,一般会以core.xxx形式命名。
如何产生Core Dump
一般来说, 当进程接收到某个信号导致进程退出或crash(崩溃)的时候, 会产生一个 core dump 文件.
比如经常遇到的数组越界或者访问空指针都会产生一个SIGSEGV型号, 导致程序崩溃, 这个时候就会产生一个core dump.
以下是默认产生 coredump 的一些信号.
3)SIGQUIT 4)SIGILL 6)SIGABRT 8)SIGFPE 11)SIGSEGV 7)SIGBUS 31)SIGSYS
5)SIGTRAP 24)SIGXCPU 25)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