当程序试图访问不允许访问的内存时就会发生段错误。这通常是因为程序中错误的使用指针造成,例如下面例子所示的对空指针的解引用。通常一个程序收到SIGSEGV信号的默认行为是非正常退出,这会终止这个进程,同时可能会产生核心转储core来帮助进行调试,或者产生其他一些和平台相关的行为。 核心转储 是某个计算机程序在特定的时刻计算机内存中的状态记录,通常是在该程序异常退出的时候产生。
下面的例子用来产生core文件。代码在bad()中解引用空指针,当我们运行时,会产生core文件。
/* bad.c */
int bad(int *pt)
{
int x = *pt;
return x;
}
int main()
{
int *ptr = 0; /* null pointer */
return bad(ptr);
}
编译和运行:
$ gcc -g -o ./bad bad.c
$ ./bad
Segmentation fault
$ ls
bad bad.c
可以看出core文件并没有产生,为了生成core文件,我们需要指定文件的大小:
$ ulimit -c
0
$ ulimit -c unlimited
$ ulimit -c
unlimited
再次运行:
$ ./bad
Segmentation fault (core dumped)
$ ls
bad bad.c core
现在 运行gdb 并用可执行文件名和core文件 作为参数:
<pre name="code" class="cpp">$ gdb ./bad core.2333
GNU gdb (GDB) Fedora (7.5.1-37.fc18)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /home/KHong/Work/Debug/bad...done.
[New LWP 2333]
Core was generated by `./bad'.
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004004f8 in bad (pt=0x0) at bad.c:5
5 int x = *pt;
(gdb) backtrace
#0 0x00000000004004f8 in bad (pt=0x0) at bad.c:5
#1 0x000000000040051e in main () at bad.c:12