常见的“段错误”程序,可以通过core dump的方式进行定位。
使用方法:
- 打开linux的core dump功能。core dump默认在linux系统中是关闭的。通过
ulimit -c unlimite 或 ulimit -c 1024
其中的-c选项是设置core dump文件大小用,后跟"unlimited"意为对文件大小不做限制,或者大小限制为1024kbytes。
2. 设置core dump的文件自动存储位置和文件名称格式。
echo "/tmp/corefile/care-%e-%p-%t" > /proc/sys/kernel/core_pattern
修改core文件生成于/tmp/corefile/目录下,并且名称格式为:core-命令名称-pid号-时间
3. 编写一段会出现段错误的代码,试验一下:
segfault.c #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) { char a[] = "hello\n"; printf("%s", a[10]); return 0; }
该处对a[10]的内存位置进行了非法访问,所以报错。编译时记得加上"-g"选项,gentoo官网上建议使用"-ggdb"选项。
gcc -g segfault.c -o segfault
执行
./segfault 段错误 (core dumped)
多了一个"core dumped"的提示,此时应该在/tmp/corefile/下找到刚刚生成的core dump转储文件。
4. 使用gdb调试查看,注意gdb命令的启动方式,使用--core参数
gdb --core=care-segfault-311-1320735463 GNU gdb 6.6 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu". (no debugging symbols found) Using host libthread_db library "/lib/libthread_db.so.1". Core was generated by `./segfault'. Program terminated with signal 11, Segmentation fault. #0 0xb7679439 in ?? () (gdb) bt #0 0xb7679439 in ?? () (gdb)
可以看到有地址,但是找不到符号表。在网上,有些使用gdb file命令调入,但是试过不能成功
(gdb) file ./segfault Reading symbols from ./segfault...done. (gdb) bt #0 0xb7679439 in ?? () #1 0xb77605a0 in ?? () #2 0x080484af in ?? () #3 0x00000000 in ?? ()
最后用的命令:gdb cmd_file core_file
gdb segfault care-segfault-311-1320735463 GNU gdb 6.6 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu"... Using host libthread_db library "/lib/libthread_db.so.1". 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 `./segfault'. Program terminated with signal 11, Segmentation fault. #0 0xb7679439 in vfprintf () from /lib/libc.so.6 (gdb) l 1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int main(int argc, char *argv[]) 5 { 6 char a[] = "hello\n"; 7 printf("%s", a[10]); 8 return 0; 9 } (gdb) bt #0 0xb7679439 in vfprintf () from /lib/libc.so.6 #1 0xb767ee24 in printf () from /lib/libc.so.6 #2 0x080483e1 in main (argc=1, argv=0xbfa460d4) at segfault.c:7 (gdb)
可以跟踪问题出在代码第7行处,即printf函数调用。
参考: