今天有人问起这个问题,于是写了个简单的例子,演示一下这个过程。
FreeBSD的
开发者手册上对此有专节论述,此外也可以参考gdb手册。
编写一个小程序:
- 1 void foo(void)
- 2 {
- 3 *(int *)0 = 1;
- 4 }
- 5
- 6 int main(void)
- 7 {
- 8 foo();
- 9 }
命名为foo.c,使用-g选项编译它,以便能够在core文件中包含调试信息,方便gdb跟踪至源代码行:
生成的文件名就是默认的a.out。
运行这个a.out程序,显然,它会在第三行处产生一个core dump,生成a.out.core文件。
我们这时就可以使用下述
命令对其进行分析:
运行结果如下:
- [~]$gdb a.out a.out.core
- GNU gdb 6.1.1 [FreeBSD]
- Copyright 2004 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 "i386-marcel-freebsd"...
- Core was generated by `a.out'.
- Program terminated with signal 11, Segmentation fault.
- Reading symbols from /lib/libc.so.6...done.
- Loaded symbols for /lib/libc.so.6
- Reading symbols from /libexec/ld-elf.so.1...done.
- Loaded symbols for /libexec/ld-elf.so.1
- #0 foo () at foo.c:3
- 3 *(int *)0 = 1;
- (gdb)
我们可以看到,这时gdb已经打印出了程序崩溃原因,以及出错的代码行位置。
如果我们想查看出问题之前的调用栈,可以使用gdb的bt命令:
- (gdb) bt
- #0 foo () at foo.c:3
- #1 0x080484bd in main () at foo.c:8
- (gdb)
我们还可以使用up和down命令在调用栈中移动,并检查相应栈内的变量值,以便分析(复杂)程序出错的真实原因。
阅读(3121) | 评论(0) | 转发(0) |