如果你对core dump和gdb很熟悉的话, 就直接跳过这篇文章好了。
先来看下如下代码段:
#include <stdio.h> void foo(char *p) { char s[] = {"foo"}; printf("%s...\n", s); *p = s[0]; return; } int main() { char *p = NULL; foo(p); return 0; }
这段代码很简单, 我们可以一眼就看出*p = s[0]; 这条语句会导致段错误, 但如果程序很复杂的话,
就需要花很长的时间去走查,显然不如有个好的调试方法来得快。
如果你比较熟悉gdb 的话, 可以用gdb来调试来找到这个段错误的语句。
如果你觉得gdb的命令有点复杂,还有一种比较简单的办法来搞定这个:就是使用coredump功能。
coredump在linux下缺省是关闭的, 我们可以用ulimit -c unlimited来打开它,这里unlimited指的是core file的大小不限, 我们当然也可以指定一个具体
数值,比如512(KB).
打开coredump后, 我们就可以编译上面的程序代码(假设文件名为:crash.c)
gcc -g -o crash crash.c
注意要加上-g开关。
生成crash可执行文件后, 执行./crash
程序会出现段错误:
foo...
段错误 (core dumped)
注意,这里段错误下面有个标记core dump说明打开了core dump功能, 否则就是没打开。
程序执行后,我们可以在当前目录下找到一个文件名:core.xxxx, 这就是core file。
xxxx指的是该程序的pid, 这个值会变化。 但也有可能没有这个值,这取决于/proc/sys/kernel/core_uses_pid文件的内容是不是1,
是1的话就会插入这个pid。 同时我们也可以在该目录下找到一个叫core-pattern的文件, 修改该文件就可以定制core file的名称和存放路径,
该文件的缺省值是core,表示core file输出到被调试程序的当前目录下, 基本文件名为 core。
找到core file后, 比如core.2002,
我们就可以执行如下命令:
gdb ./crash core.2002
就会输出如下调试信息:
...
Core was generated by `./crash'.
Program terminated with signal 11, Segmentation fault.
#0 0x080483ac in foo (p=0x0) at crash.c:9
9 *p = s[0];
看出来了吧,产生段错误的第几行,什么语句都在里面了。