1、GDB调试
1)第一步是使用带有调试标志(debugging flags)的方式编译这段代码,如下:
# gcc -g segfault.c
2)运行可执行程序
$:gdb a.out //进入gdb模式
(gdb) run //运行程序
Starting program: /home/dgawd/cpsc/363/a.out test string Program received signal SIGSEGV, Segmentation fault. 0x4007fc13 in _IO_getline_info () from /lib/libc.so.6
(gdb) backtrace //查看堆栈内容 #0 0x4007fc13 in _IO_getline_info () from /lib/libc.so.6 #1 0x4007fb6c in _IO_getline () from /lib/libc.so.6 #2 0x4007ef51 in fgets () from /lib/libc.so.6 #3 0x80484b2 in main (argc=1, argv=0xbffffaf4) at segfault.c:10 #4 0x40037f5c in __libc_start_main () from /lib/libc.so.6
(gdb) frame 3 //关注自己代码问题,查看3号堆栈帧内容 #3 0x80484b2 in main (argc=1, argv=0xbffffaf4) at segfault.c:10 10 fgets(buf, 1024, stdin)
(gdb) print buf //打印buf中的内容
$1 = 0x0 //buf 为空指针
(gdb) kill //kill 当前程序而不退出gdb
Kill the program being debugged? (y or n) y
(注意:不用使用quit直接退出gdb,这样比较麻烦。直接kill掉当前的程序调用即可)
(gdb) break segfault.c:8 //在第8行设置断点
Breakpoint 1 at 0x8048486: file segfault.c, line 8.
(gdb) run //再次运行程序
Starting program: /home/dgawd/cpsc/363/a.out
Breakpoint 1, main (argc=1, argv=0xbffffaf4) at segfault.c:8
8 buf = malloc(1<<31);
(gdb) next //单步调试
10 fgets(buf, 1024, stdin)
2、backtrace和backtrace_symbols
这两个函数通过回溯的方式反映函数调用关系
1)这两个函数能显示正确结果的前提条件:
(1)编译程序时,gcc的优化选项是0
(2)内联函数没有栈
2)makefile编写注意事项(1)编译时选项为“-g - O0” CFLAGS = -g -O0
(2)链接时选项为“-rdynamic” LDFLAGS = -rdynamic