[serious@localhost c]$ gdb gdbtest GNU gdb (GDB) 7.5 Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later 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 "x86_64-unknown-linux-gnu". For bug reporting instructions, please see: ... Reading symbols from /home/serious/Desktop/c/gdbtest...done. (gdb) // 这里就可以开始输入命令进行调试了
首先列出程序的内容(当然,你也可以另开一个终端界面使用 vim 的 set nu 功能显示行号)
(gdb) list 1 #include <stdio.h> #include <stdlib.h> #include <string.h>
list 命令会一次性列出 10 行源代码,list 后面加上 1 是确保可以从第一行开始显示源代码。
后面的就不列出了。我们在几个关键的位置加上断点:
``` bash (gdb) break 7 Breakpoint 1 at 0x4006ac: file gdbtest.c, line 7. (gdb) break 12 Breakpoint 2 at 0x4006d5: file gdbtest.c, line 12. (gdb) b 15 Breakpoint 3 at 0x400707: file gdbtest.c, line 15. (gdb) b 27 Breakpoint 4 at 0x400777: file gdbtest.c, line 27. (gdb) b 29 Breakpoint 5 at 0x400783: file gdbtest.c, line 29.
然后看看我们所设置的断点:
(gdb) info break Num Type Disp Enb Address What 1 breakpoint keep y 0x00000000004006ac in reverse at gdbtest.c:7 2 breakpoint keep y 0x00000000004006d5 in reverse at gdbtest.c:12 3 breakpoint keep y 0x0000000000400707 in reverse at gdbtest.c:15 4 breakpoint keep y 0x0000000000400777 in main at gdbtest.c:27 5 breakpoint keep y 0x0000000000400783 in main at gdbtest.c:29
Num 代表断点的序号,如果我们想要禁用某个断点,可以使用 disable n 命令;如果想要删除,则使用 delete n 命令。如果要全部禁用(或删除),则不需要带 n。
Type 代表断点的类型。有 breakpoint, watchpoint 和catchpoint三种类型。
breakpoint: 就是传说中的断点啦。
watchpoint: 监控变量(或表达式)
catchpoint: 监控事件。
Disp 代表当走到当前断点时,如果此断点已被禁用,是否要显示该信息。
Enb 是断点当前是否是启用的。启用为 y,禁用为 n。
Address 是断点的地址。每一个断点也是有分配相应的内存的。
What 是断点的详细信息,包括所在的函数名及所在源代码行数。
开始调试:
(gdb) run // 运行程序 Starting program: /home/serious/Desktop/c/gdbtest Breakpoint 4, main (argc=1, argv=0x7fffffffe1a8) at gdbtest.c:27 27 reverse(str); (gdb) continue // 继续运行程序直到下一个断点 Continuing. Breakpoint 1, reverse (string=0x601010 "hello world!") at gdbtest.c:7 7 int nLength = strlen(string); (gdb) next // 执行一行代码 8 char * temp = (char*)malloc(nLength); (gdb) print nLength // 查看 nLength 的值 $10 = 12 // 长度是正确的 (gdb) next 10 for(int i = 0; i < nLength; i++) (gdb) next Breakpoint 2, reverse (string=0x601010 "hello world!") at gdbtest.c:12 12 temp[i] = string[nLength - i]; (gdb) next 10 for(int i = 0; i < nLength; i++) (gdb) next Breakpoint 2, reverse (string=0x601010 "hello world!") at gdbtest.c:12 12 temp[i] = string[nLength - i]; (gdb) print temp // 查看 temp 的值 $11 = 0x601030 "" (gdb) continue Continuing. Breakpoint 2, reverse (string=0x601010 "hello world!") at gdbtest.c:12 12 temp[i] = string[nLength - i]; (gdb) print temp $12 = 0x601030 "" // 已经发现问题了,连续赋值两次,temp 却一直是"" (gdb)
(gdb) n 10 for(int i = 0; i < nLength; i++) (gdb) watch temp[i] Hardware watchpoint 12: temp[i] (gdb) c Continuing. Hardware watchpoint 12: temp[i] Old value = 0 '\000' New value = 33 '!' reverse (string=0x601010 "hello world!") at gdbtest.c:10 10 for(int i = 0; i < nLength; i++) (gdb)