目录
(四).断点(b、info b、d、c、disable、enable)
(五).打印变量和数组(p、display、undisplay)
首先,我们需要将文件编译为debug版本。因为在linux系统下,默认生成的可执行程序是release版,但是调试需要debug版本。
我们需要在gcc或g++命令后加上限定符-g。这样生成的程序就是debug版本的。
方式如下:
gcc/g++ -g test.c/test.cpp -o test
*gdp会自动记录最近的命令,如果没有输入其他命令,可以按enter键继续执行最近命令。
l 命令是用来查看代码内容的。使用方式为
l 行号 默认生成10行,当指定行号时,会生成以指定行号为中间的共10行代码
默认不指定行号时:
- (gdb) l
- 1 #include
- 2 #include
- 3 #include
- 4 #include
- 5 #include
- 6 #include
- 7 using namespace std;
- 8 int main()
- 9 {
- 10 char arr[102] = { 0 };
- (gdb)
指定行号:
- (gdb) l 10
- 5 #include
- 6 #include
- 7 using namespace std;
- 8 int main()
- 9 {
- 10 char arr[102] = { 0 };#会以第10行为中心
- 11 const char* Lop = "|/-\\";
- 12 memset(arr, 0, sizeof(arr));
- 13 int i = 0;
- 14 for(i = 0; i <= 100; i++)
- (gdb)
r命令用来开始代码调试工作,使用方式如下:
r 开始调试,直到程序结束或遇到断点暂停。在调试过程中,再次使用r命令会重新开始调试。
where 查看此时执行位置

b 行号 在指定行打断点
info b 显示全部断点信息,也可以在b后加编号显示指定断点
- (gdb) b 10 #打断点
- Breakpoint 3 at 0x400ac8: file cdl.cpp, line 10.
- (gdb) b 15
- Breakpoint 4 at 0x400b23: file cdl.cpp, line 15.
- (gdb) info b #显示断点
- Num Type Disp Enb Address What
- 3 breakpoint keep y 0x0000000000400ac8 in main() at cdl.cpp:10
- 4 breakpoint keep y 0x0000000000400b23 in main() at cdl.cpp:15
- (gdb)
d 断点编号 删除指定断点,不加编号则删除全部
注意断点编号不是行号,可以使用info来查看。

- (gdb) info b
- Num Type Disp Enb Address What
- 5 breakpoint keep y 0x0000000000400ac8 in main() at cdl.cpp:7
- 6 breakpoint keep y 0x0000000000400ac8 in main() at cdl.cpp:10
- 7 breakpoint keep y 0x0000000000400b23 in main() at cdl.cpp:15
- 8 breakpoint keep y 0x0000000000400b39 in main() at cdl.cpp:17
- (gdb) d 5 #删除指定断点
- (gdb) d #删除全部断点
- Delete all breakpoints? (y or n) y
- (gdb) info b
- No breakpoints or watchpoints.
- (gdb)
c 从当前调试位置直接执行到下一个断点处
- #断点为10、17、18行
- Num Type Disp Enb Address What
- 1 breakpoint keep y 0x0000000000400ac8 in main() at cdl.cpp:10
- 2 breakpoint keep y 0x0000000000400b39 in main() at cdl.cpp:17
- 3 breakpoint keep y 0x0000000000400c04 in main() at cdl.cpp:20
- (gdb) r #执行到第10行暂停
-
- Breakpoint 1, main () at cdl.cpp:10
- 10 char arr[102] = { 0 };
- (gdb) c #执行到第17行暂停
- Continuing.
-
- Breakpoint 3, main () at cdl.cpp:17
- 17 cout << '[' << setw(100) << arr << ']' << '[' << i << '%' << ']' << Lop[i % 4] << '\r';
- (gdb)
disable 断点编号 关闭断点
注意,关闭断点并不是删除断点。只是在调试时不会在该处暂停,但是断点依旧存在。
使用info b即可看断点关闭与否。
6.打开断点enable 变量编号 打开断点
同样的,指令需要输入的也是断点编号

p 变量 打印对应的变量值,打印地址直接加取地址符&即可
需要注意的是,这种方法只能显示一次变量值,当继续调试时变量不再显示。
- (gdb) p i
- $5 = 4
- (gdb) n
- 14 for(i = 0; i <= 100; i++)
- (gdb) #变量i没有再次显示
如果我们需要打印数组的值,输入数组名即可。

如果我们需要在调试中一直显示某个变量的值,那么就需要display命令了。
display 变量 常显示指定变量值,使用方式与p一致
- (gdb) display arr
- 3: arr = "---------", '\000'
times> - (gdb) c
- Continuing.
- [--------- ][9%]/
- Breakpoint 1, main () at cdl.cpp:17
- #arr数组常显示
- 3: arr = "----------", '\000'
times> - (gdb)
undisplay 常显示变量编号 删除指定常显示变量
需要注意的是,不能直接写变量名,变量编号使用info display即可知道。

s 逐语句调试。相当于vs中的F11
n 逐过程调试。相当于vs中的F10
bt 查看当前堆栈调用
主要用于调试至函数内部或者递归调用函数时。
我们以一个递归程序举例:
- #include
- void func(int i);
- void func(int i)
- {
- if(i == 0) return;
- printf("hello world\n");
- func(i - 1);
- }
-
- int main()
- 3 {
- 4 func(3);
- 5 return 0;
- 6 }
当我们执行至i == 1时:

finish 可以直接跑完当前函数,若函数只有一层则直接跑完函数。
如果是函数递归调用,当还没开始递归时,finish会执行完整个函数,自动走完全部递归过程(前提无断点)。
当已经递归调用后,在哪一层递归finish就会返回至它的前一层。
我们依旧以上一个递归程序为例:

3.执行至指定行until 行号 执行至指定行
- 1 #include"head.h"
- 2 void func(int i)
- 3 {
- 4 if(i == 0) return;
- 5 printf("hello world\n");
- 6 func(i-1);
- 7 }
- (gdb) until 5
- func (i=3) at function.c:5
- 5 printf("hello world\n");
- 1: i = 3
- (gdb)
until也可以在main函数中使用,但一般until用于小范围跳动。
disassemble 查看指令附近区域的反汇编

shell 指令 在gdb界面中执行linux指令

(gdb) quit
- (gdb) quit
- A debugging session is active.
-
- Inferior 1 [process 10341] will be killed.
-
- Quit anyway? (y or n) y
- [cdl@VM-16-9-centos ~]$
如有错误,敬请斧正