一、core dump
1.何谓 core dump?
    在使用半导体作为内存的材料前,人类是利用线圈当作内存的材料,线圈就叫作 core ,用线圈做的内存就叫作core memory。如今,半导体工业澎勃发展,已经没有人用core memory 了,不过,在许多情况下,人们还是把记忆体叫作core 。
    我们在开发(或使用)一个程序时,最怕的就是程序莫明其妙地当掉。虽然系统没事,但我们下次仍可能遇到相同的问题。于是这时操作系统就会把程序当掉 时的内存内容 dump 出来(现在通常是写在一个叫 core的file里面),让 我们或是debugger 做为参考。这个动作就叫作 core dump。
    在 C/C++语言中,最常发生错误的地方就是指 针有问题。您可以利用 core 文件和debugger工具(gdb)把错误找出来。除了SIGSEGV(无效内存访问)信号以外,SIGABRT(异常终止), SIGBUS(硬件故障),SIGEMT(硬件故障),SIGFPE(算术异常),SIGILL(非法硬件指令),SIGIOT(硬件故障),SIGQUIT,SIGSYS(无效系统调用),SIGTRAP(硬件故障)等。

 
2.设置core dump
    如果完全用不到调试程序,那么用不到核心转储功能。
    要怎么才不会让 core 文件出现
    如果用的是bash的话, 在/etc/profile里加上(或者修改)一条:
    ulimit -c 0
    如果想让系统在信号中断造成的错误时产生core文件, 我们需要在shell中按如下设置:
    首先查看一下现在的设置: #ulimit -a
    #ulimit -c unlimited #设置core大小为无限
    #ulimit unlimited #设置文件大小为无限
    有些系统发行版本没有默认开启core dump功能,需要将上面的命令加入shell的配置文件,例如~/.bashrc。如果要加入全局配置文件/etc/profile中,这些需要有root权限。
    配置生成core文件的相关参数/proc/sys/kernel/core_uses_pid文件可以控制core文件的文件名是否以pid作为扩展。如果文件内容为1表示添加pid作为扩展,生成core文件的格式为core.xxx;为0表示生成的core文件与运行的程序同名。
    /proc/sys/kernel/core_pattern文件可以控制core文件保存位置和文件名格式,例如
#echo "/corefile/core-e%-%p-%t" > /proc/sys/kernel/core_pattern
#mkdir /corefile
    则保存路径是~/corefile,格式是core-命令名-pid-时间戳 ,其他参数:
%u current uid
%g current gid
%s insert signal that caused the coredump
%h host name where the coredump occurred

 
二、gdb调试简介
(1).GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:
·   Start your program, specifying anything that might affect its behavior.
·   Make your program  stop on specified  conditions.
·   Examine  what  has happened, when your program has stopped.
·   Change things in your program, so you can experiment  with correcting the effects of one bug and go on to learn about another.
(2).start GDB
$gdb
$gdb program
$gdb program core
$gdb program proc-pid #attch GDB to process proc-pid(unless you also have a core file same name as proc-pid; GDB check for a core dump file firsts) 
(3). frenquently GDB commands
break or b[file:]function Set a breakpoint at function (in file). e.g.b main
run or r [arglist] Start your program (with  arglist,  if  specified).
bt Backtrace: display the program stack.
print expr Display the value of an expression.
c Continue running your program (after stopping,e.g. at a breakpoint).
next or n  Execute next program  line  (after  stopping);step over any function calls in the line.
edit [file:]function look at the program line where it is presently stopped.
list [file:]function type the text of the program in  the  vicinity  of where it is presently stopped.
step or s   Execute  next  program  line (after stopping); step into any function calls in the line.
help [name] Show information about GDB  command  name,  or general information about using GDB.
set width 70 #设置标准屏幕为70列
quit or q Exit from GDB.
for example:
//test.c
(gdb) b main
Breakpoint 1 at 0x400534: file test.c, line 19.
(gdb) b func1
Breakpoint 2 at 0x400524: file test.c, line 13.
(gdb) r
Starting program: /home/luffy/workspace/myapue/test 
Breakpoint 1, main () at test.c:19
19    func1(); #noted that the next line is calling a function named func1
(gdb) l #list the current location
14 }
15
16 int
17 main()
18 {
19    func1();
20    return 0;
21 }
(gbd) s #step into func1
Breakpoint 2, func1 () at test.c:13
13 func();
(gbd) l 5 #let's have a view of this func
10 void
11 func1()
12 {
13 func();
14 }
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400508 in func () at test.c:7
7   printf("%d\n", *p);
(gdb) bt
...show informations about stack...
(gdb) c
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) q
另外,print可以显示当前变量的内容。例如p int_var, array_var或struct_var等等。

 
三、core dump调试技术
1.  为了使用gdb进行程序调试,需要在编译程序中加入供gdb使用的调试信息。方法是在
编译程序时使用:
-g gdb输出debug调试信息
-DDEBUG 传入宏DEBUG
-UDEBUG 取消宏DEBUG
举例如下
利用gcc的 -DDEBUG选项。
(1).源文件DEBUG.c中有:
#include <stdio.h>
int main(int argc, char *argv[])
{
#ifdef DEBUG
    printf("DEBUG is definded \n");
#else
    printf("DEBUG is not definded \n");
#endif
}
(2). 输入:$gcc -g -o debug DEBUG.c
        $./debug
   out: DEBUG is not definded
(3). 输入:$gcc -DDEBUG -g -o debug DEBUG.c
        $./debug
   out: DEBUG is definded
release版本编译
除去 -g -DDEBUG,并且加上 -o3 : 最大优化代码

 
2. 一个简单的例子
//test.c
#include <stdio.h>

void
func()
{
     int *p = NULL;
     printf("%d\n", *p);
}

int
main()
{
        func();
        return 0;
}

 
$gcc -g -o test test.c
$./test.c
out:段错误(核心已转储)
如果没有转储,是因为默认选项的问题。通过echo "ulimit -S -c unlimited > /dev/null 2>&1" >>~/.bashrc,然后应用该配置文件. ~/.bashrc即可。

 
3. 直接从core文件里获得出错信息,有  
$gdb -c core
$ gdb -c core-e3926-1311507364 
......
[New Thread 3926]
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
(gdb) bt
#0  0x0000000000400508 in ?? ()
#1  0x0000000000000000 in ?? ()
(gdb) q
有时候并不能获得有效信息。

 
4. 用gdb查看core文件:
下面我们可以在发生运行时信号引起的错误时发生core dump了.
发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发core dump的行.
gdb [exec file] [core file]
或者gdb --core=[core file] [exec file]或者gdb -c [core file] [exec file] 
如:
gdb ./test test.core
在进入gdb后, 用bt(backtrace: display the program stack)命令查看backtrace以检查发生程序运行到哪里, 来定位core dump的文件->行.
Core was generated by `./test.o'.
Program terminated with signal 11, Segmentation fault.
#0  0x0000000000400508 in func () at test.c:7
7   printf("%d\n", *p);
(gdb) bt
#0  0x0000000000400508 in func () at test.c:7
#1  0x000000000040052e in main () at test.c:13
(gdb) q

 
Reference:
APUE
man gdb
Linux core dump file http://apps.hi.baidu.com/share/detail/30247650
Linux下使用core文件调试程序 http://www.docin.com/p-235044288.html
gdb简介 http://www.360doc.com/content/07/0119/10/4910_336656.shtml