|
在写 Linux 程序时,经常会遇到“段错误”(segmentation fault) 这样的问题。如果程序比较大,那么如果用 gdb 调试可能显得比较吃力。这时可以用 core dump 文件来进行分析。
那什么是 core dump 文件呢?
core dump 文件就是在程序发生错误时,由操作系统把程序错误时的相应内容 dump 出来,然后存储在一个文件中,这个文件就是当时的内存映像,也就是 core dump 文件。
造成“段错误”产生的原因经常是因为指针的乱用。比如下面这个测试程序:#include <stdio.h>
int main()
{
char *p = "hello world";
*(p+1) = 'X';
printf ("%s\n", p);
return (0);
} 在上面的程序中,hello world 字符串在编译时就会被分配到 .rodata 区域,相当于属于 const 类型,是不能进行修改的。然后在程序里,却用指针进行了更改,那么这个程序在运行起来,就会产生段错误:# ./coredump_test.exe
段错误 (core dumped) 我的系统是 CentOS 5.3 ,是 RedHat 5.3 的编译版,而 RedHat 在默认情况下是不错产生 core dumped 文件的。而上面,在括号里提示 core dumped ,则表示已经产生了 core dumped 文件。使能产生 core dumped 文件的方法是:ulimit -S -c unlimited > /dev/null 2>&1 关于 ulimit 命令的用法见:http://www.groad.net/bbs/read.php?tid-1471.html
使用 gdb 与 core dumped 来定位错误
当运行程序出错后,会产生 core dumped 文件,此时可用 gdb 和 core dumped 配合来定位程序的错误,使用方法是:
像上面的程序,生成的可执行文件名叫做 coredump_test.exe ,现在运行它出错了,可以在与程序同一个目录下观察到生成的 core dumped 文件:core.10852 。这里 core.10852 中的 10852 是当时程序运行的 pid 值。关于如何控制生成 core dumped 文件见:http://www.groad.net/bbs/read.php?tid-1470.html
现在进行调试:gdb coredump_test.exe core.10852
出现提示信息:[root@localhost ~]# gdb coredump_test.exe core.10852
GNU gdb Fedora (6.8-27.el5)
Copyright (C) 2008 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 "i386-redhat-linux-gnu"...
warning: core file may not match specified executable file.
warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./coredump_test.exe'.
Program terminated with signal 11, Segmentation fault.
[New process 10852]
#0 0x080483a2 in main () at coredump_test.c:7
7 *(p+1) = 'X'; 由上面的信息可见,已经定位出了出错的行!这里,就是乱用了指针去修改固化字符串的结果,这是不允许的!
注意,想让 core dumped 可以正常工作,在编译可执行文件时,必须用 -g 调试选项来编译生成文件。 |
|