GDB调试core文件(2)

来源:互联网 发布:php framework框架 编辑:程序博客网 时间:2024/05/21 09:59

使用gdb和core dump迅速定位段错误
关键字:gdb、段错误、core dump

一、什么是core dump

core:内存、核心的意思;dump:抛出,扔出;core dump:前提:当某程序崩溃的一瞬间,内核会抛出当时该程序进程的内存详细情况,存储在一个名叫core.xxx(xxx为一个数字,比如core.699)的文件中。

二、更改生成的core文件的大小限制

可见,core文件是内核生成的,那某一个进程因为段错误而崩溃的时候的内存映像很大,那必然会生成一个很大的core文件,所以我们可以通过ulimit命令来设置生成core文件的大小,例如$ulimit -c unlimited,这里就是设置生成的core文件无大小限制。

三、生成core文件

当第二步完成了,就运行一次那个有问题的程序,然后自然就会因为段错误而崩溃,在当前目录下就生成了core.xxx文件。

四、分析core文件

使用命令$gdb 程序名 core.xxx,然后再输入where就可以看到产生段错误的地方。

五、实例分析

1.test.c文件的源代码

void do_it();int main(){        do_it();        return 0;}void do_it(){        char* p = 1; //定义一个字符指针变量a,指向地址1,这个地址肯定不是自己可以访问的,但是这行不会产生段错误        *p = 'a'; //真正产生段错误的在这里,试图更改地址1的值,此时内核会终止该进程,并且把core文件dump出来}

2.编译该源代码,请注意,加-g标签,可以在where命令后看到更加详细的信息。

运行编译命令:$gcc -g ./test.c,看到如下打印
[michael@localhost core_dump]$ gcc -g ./test.c ./test.c: In function ‘do_it’:./test.c:9:19: warning: initialization makes pointer from integer without a cast[michael@localhost core_dump]$ 

从而得到带调试信息的(因为加了-g 编译标签)a.out二进制文件。

3.设置core文件大小限制为无限大。

运行命令:$ulimit -c unlimited,即可。

4.生成core文件。

运行命令:$./a.out,即可,可看到如下打印:

[michael@localhost core_dump]$ ./a.out Segmentation fault (core dumped)[michael@localhost core_dump]$ 

运行命令:$ll,可看到如下打印:

[michael@localhost core_dump]$ lltotal 80-rwxrwxr-x. 1 michael michael   5612 May  2 15:54 a.out-rw-------. 1 michael michael 204800 May  2 15:58 core.7369-rw-rw-r--. 1 michael michael    383 May  2 15:53 test.c[michael@localhost core_dump]$ 

5.使用gdb调试core文件。

运行命令:$gdb ./a.out ./core.7369,可看到如下打印:

[michael@localhost core_dump]$ gdb ./a.out ./core.7369 GNU gdb (GDB) Fedora (7.2-52.fc14)Copyright (C) 2010 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>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 "i686-redhat-linux-gnu".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /home/michael/core_dump/a.out...done.[New Thread 7369]Missing separate debuginfo for Try: yum --disablerepo='*' --enablerepo='*-debuginfo' install /usr/lib/debug/.build-id/c4/1c574f31a203492b9389c783adad6ff1989915Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.Loaded symbols for /lib/ld-linux.so.2Core was generated by `./a.out'.Program terminated with signal 11, Segmentation fault.#0  0x080483b8 in do_it () at ./test.c:1010        *p = 'a'; //真正产生段错误的在这里,试图更改地址1的值,此时内核会终止该进程,并且把core文件dump出来Missing separate debuginfos, use: debuginfo-install glibc-2.13-2.i686(gdb) 

运行命令:where,即可看到出现段错误的行数了,如下打印:

(gdb) where#0  0x080483b8 in do_it () at ./test.c:10#1  0x0804839f in main () at ./test.c:4(gdb) 
在第10行,很容易吧。
0 0