转载:http://leonzhan.iteye.com/blog/803008
Linux下的C程序常常会因为内存访问错误等原因造成segment fault(段错误),此时如果系统core dump功能是打开的,那么将会有内存映像转储到硬盘上来,之后可以用gdb对core文件进行分析,还原系统发生段错误时刻的堆栈情况。这对于我们发现程序bug很有帮助。
使用ulimit -a可以查看系统core文件的大小限制;使用ulimit -c [kbytes]可以设置系统允许生成的core文件大小,例如
- ulimit -c 0 不产生core文件
- ulimit -c 100 设置core文件最大为100k
- ulimit -c unlimited 不限制core文件大小
先看一段会造成段错误的程序:
- #include <stdio.h>
- int main()
- {
- char *ptr="linuxers.cn";
- *ptr=0;
- }
编译运行后结果如下:
- [leconte@localhost test]$ gcc -g -o test a.c
- [leconte@localhost test]$ ./test
- 段错误
此时并没有产生core文件,接下来使用ulimit -c设置core文件大小为无限制,再执行./test程序,结果如下:
- [leconte@localhost ~]$ ulimit -a
- core file size (blocks, -c) 0
- .........
- [leconte@localhost test]$ ulimit -c unlimited
- [leconte@localhost test]$ ulimit -a
- core file size (blocks, -c) unlimited
- ..............
- [leconte@localhost test]$ ./test
- 段错误 (core dumped)
- [leconte@localhost test]$ ls -al core.*
- -rw------- 1 leconte leconte 139264 01-06 22:31 core.2065
可见core文件已经生成,接下来可以用gdb分析,查看堆栈情况:
- [leconte@localhost test]$ gdb ./test core.2065
- 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: exec file is newer than core 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 `./test'.
- Program terminated with signal 11, Segmentation fault.
- [New process 2065]
- #0 0x0804836f in main () at a.c:6
- 6 *ptr=0;
从上述输出可以清楚的看到,段错误出现在a.c的第6行,问题已经清晰地定位到了。
很多系统默认的core文件大小都是0,我们可以通过在shell的启动脚本/etc/bashrc或者~/.bashrc等地方来加入 ulimit -c 命令来指定core文件大小,从而确保core文件能够生成。
除此之外,还可以在/proc/sys/kernel/core_pattern里设置core文件的文件名模板,详情请看core的官方man手册。
PS:
总结一下:
1. ulimit -c unlimited
2. 编译时加上 -g 参数
3. gdb ./testcore
这种方法相比使用打印来跟踪死机问题就好比,一个骑摩托车,一个走路了。不过这个方法虽好,还是有一定局限性, 因为需要跑 debug 版的程序, 然而正式测试的程序通常都是release版的, 因此在测试出死机问题时往往不会生成core文件,或者core文件中没有足够的信息定位死机的地方。
更加厉害的办法应该是堆栈回溯, 通过这种方法只要抓到死机堆栈, 就能解决问题, 而死机堆栈可以更加容易获得。缺点就是这个方法比较难,需要懂一些汇编。目前本人也正在学习堆栈回溯的方法。
注意:如果生成的core一直是0, 有可能是文件系统的原因导致, 比如你在window下通过虚拟机共享windows的文件夹到linux下,这就会有问题, 这时可以将测试文件放到用户根目录(~/)下应该就可以了。
Linux下C程序段错误分析与核心文件生成

1888

被折叠的 条评论
为什么被折叠?



