- GNU 调试器有用的资源
- GDB - 快速指南
- GDB - 资源
GDB - 调试示例 2
让我们编写另一个程序,该程序会因未初始化内存而产生核心转储。
#include <iostream> using namespace std; void setint(int*, int); int main() { int a; setint(&a, 10); cout << a << endl; int* b; setint(b, 10); cout << *b << endl; return 0; } void setint(int* ip, int i) { *ip = i; }
为了启用调试,必须在 -g 选项下编译程序。
$g++ -g crash.cc -o crash
注意:我们使用 g++ 编译器,因为我们使用了 C++ 源代码。
在 Linux 计算机上运行此程序时,它将产生以下结果
segmentation fault (core dumped)
现在让我们使用 gdb 进行调试
$ gdb crash (gdb) r Starting program: /home/tmp/crash 10 10 Program received signal SIGSEGV, Segmentation fault. 0x4000b4d9 in _dl_fini () from /lib/ld-linux.so.2 (gdb) where #0 0x4000b4d9 in _dl_fini () from /lib/ld-linux.so.2 #1 0x40132a12 in exit () from /lib/libc.so.6 #2 0x4011cdc6 in __libc_start_main () from /lib/libc.so.6 #3 0x080485f1 in _start () (gdb)
遗憾的是,该程序不会在用户定义的任何函数中(main 或 setint)崩溃,因此没有有用的跟踪或局部变量信息。在这种情况下,逐步浏览程序可能更有用。
(gdb) b main # Set a breakpoint at the beginning of the function main (gdb) r # Run the program, but break immediately due to the breakpoint. (gdb) n # n = next, runs one line of the program (gdb) n (gdb) s setint(int*, int) (ip=0x400143e0, i=10) at crash2.C:20 # s = step, is like next, but it will step into functions. # In this case the function stepped into is setint. (gdb) p ip $3 = (int *) 0x400143e0 (gdb) p *ip 1073827128
*ip 的值是由 ip 指向的整数的值。在本例中,它是一个非正常值,有力证明存在问题。本例中的问题是,指针从未正确初始化,因此它指向内存中的某个随机区域(地址 0x40014e0)。非常幸运的是,向 *ip 赋值的过程并不会导致程序崩溃,但它引发的问题会在程序结束后导致其崩溃。
gdb_debugging_examples.htm
广告