关注公众号 “融码一生”,领取全套 PDF / 电子书
- GDB 调试器支持 3 种断点:普通断点(break 命令)、观察断点(watch 命令)以及捕捉断点(catch 命令)。可以在被调试程序中打多个断点,GDB 甚至允许在同一位置打多个断点。
- 这就产生一个问题,如果之前建立的断点不再需要,该如何删除或禁用?常用的方式有 2 种:
-
- 使用 quit 命令退出调试,然后重新对目标程序启动调试(会消除上一次调试操作中建立的所有断点)
- 使用专门删除或禁用断点的命令,既可以删除某一断点,也可以删除全部断点
#include <stdio.h>
int main(){
int num = 0;
scanf("%d", &num);
printf("%d", num);
return 0;
}
- 编译:
gcc main.c -o main.out -g
ls
:<<!
main.c main.out
!
1、查看当前已建好的断点
- 查看当前调试环境中已建好且尚未删除的断点。
- 查看当前调试环境中存在的所有断点(普通断点、观察断点以及捕捉断点):
-
(gdb) info breakpoint [n]
(gdb) info break [n]
-
-
n
:可选参数,为某个断点的编号,表示查看指定断点而非全部断点- 任何类型的断点在建立时,GDB 调试器都会为其分配一个独一无二的断点编号。
-
- 建立如下断点:
gdb main.out -q
:<<!
Reading symbols from /root/tmp/main.out...done.
!
(gdb) b 1
:<<!
Breakpoint 1 at 0x4005a5: file main.c, line 1.
!
(gdb) r
:<<!
Starting program: /root/tmp/main.out
Breakpoint 1, main () at main.c:3
3 int num = 0;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-325.el7_9.x86_64
!
(gdb) watch num
:<<!
Hardware watchpoint 2: num
!
(gdb) catch throw int
:<<!
Junk at end of arguments.
!
# jy: 注意, 该断点似乎没成功建立, 成功建立的标志应为:
:<<!
Catchpoint 3 (throw)
!
- 可以看到,我们通过 break 命令建立一个普通断点(编号为 1);通过 watch 命令建立了一个观察断点(编号为 2);通过 catch 命令建立了一个捕捉断点(编号为 3)。
- 在此基础上,可以通过
info break
或info breakpoint
命令,查看断点的具体信息:
(gdb) info break
:<<!
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005a5 in main at main.c:1
breakpoint already hit 1 time
2 hw watchpoint keep y num
!
(gdb) info break 1
:<<!
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005a5 in main at main.c:1
breakpoint already hit 1 time
!
- 以上输出信息中各列的含义分别是:
-
- 断点编号(Num)
- 断点类型(Type)
- 临时断点还是永久断点(Disp)
- 目前是启用状态还是禁用状态(Enb)
- 断点的位置(Address)
- 断点当前的状态(作用的行号、已经命中的次数等,用 What 列表示)
- 除此之外,对于调试环境中已建好且未删除的观察断点,也可以使用
info watchpoint
命令进行查看,语法格式:
-
(gdb) info watchpoint [n]
-
-
n
:可选参数,为某个观察断点的编号
-
- 继续在上面的调试环境中,执行如下指令:
(gdb) info watchpoint
:<<!
Num Type Disp Enb Address What
2 hw watchpoint keep y num
!
(gdb) info watchpoint 1
:<<!
No watchpoint matching '1'.
!
- 由于当前环境中仅有 1 个观察断点,因此
info watchpoint
命令仅罗列了编号为 2 的观察断点的信息。 - 注意:该命令仅能用于查看观察断点,普通断点和捕捉断点无法使用该命令。
2、GDB 删除断点
- 无论是普通断点、观察断点还是捕捉断点,都可以使用
clear
或delete
命令进行删除。
(1)clear 命令
- clear 命令可以删除指定位置处的所有普通断点,语法格式:
-
(gdb) clear location
-
-
location
:通常为某一行代码的行号或某个具体的函数名。当 location 参数为某个函数的函数名时,表示删除位于该函数入口处的所有断点。
-
- 在上面调试环境中,继续执行:
(gdb) clear 1
:<<!
Deleted breakpoint 1
!
(gdb) info break
:<<!
Num Type Disp Enb Address What
2 hw watchpoint keep y num
!
- 可以看到,断点编号为 1、位于程序第 1 行代码处的普通断点已经被删除了。
(2)delete 命令
- delete(d )命令通常用来删除所有断点,也可以删除指定编号的各类型断点,语法格式:
-
delete [breakpoints] [num]
-
-
breakpoints
参数可有可无num
:指定断点的编号
-
(gdb) delete 2
(gdb) info break
:<<!
No breakpoints or watchpoints.
!
(gdb)
- delete 命令删除了编号为 2 的观察断点。
- 如果不指定 num 参数,则 delete 命令会删除当前程序中存在的所有断点。例如:
gdb main.out -q
:<<!
Reading symbols from /root/tmp/main.out...done.
!
(gdb) break 1
:<<!
Breakpoint 1 at 0x4005a5: file main.c, line 1.
!
(gdb) r
:<<!
Starting program: /root/tmp/main.out
Breakpoint 1, main () at main.c:3
3 int num = 0;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-325.el7_9.x86_64
!
(gdb) watch num
:<<!
Hardware watchpoint 2: num
!
(gdb) delete
:<<!
Delete all breakpoints? (y or n) y
!
(gdb) info break
:<<!
No breakpoints or watchpoints.
!
3、GDB 禁用/激活断点
- 所谓禁用,就是使目标断点暂时失去作用,必要时可以再将其激活,恢复断点原有的功能。
- 禁用断点可以使用 disable 命令,语法格式:
-
disable [breakpoints] [num...]
-
-
breakpoints
参数可有可无num...
:表示可以有多个参数,每个参数都为要禁用断点的编号。如果指定num...
,disable 命令会禁用指定编号的断点;反之会禁用当前程序中所有的断点。
-
gdb main.out -q
:<<!
Reading symbols from /root/tmp/main.out...done.
!
(gdb) break 1
:<<!
Breakpoint 1 at 0x4005a5: file main.c, line 1.
!
(gdb) r
:<<!
Starting program: /root/tmp/main.out
Breakpoint 1, main () at main.c:3
3 int num = 0;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-325.el7_9.x86_64
!
(gdb) watch num
:<<!
Hardware watchpoint 2: num
!
(gdb) info break
:<<!
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005a5 in main at main.c:1
breakpoint already hit 1 time
2 hw watchpoint keep y num
!
(gdb) disable
(gdb) info break
:<<!
Num Type Disp Enb Address What
1 breakpoint keep n 0x00000000004005a5 in main at main.c:1
breakpoint already hit 1 time
2 hw watchpoint keep n num
!
(gdb)
Enb
列用n
表示断点处于禁用状态,用y
表示断点处于激活状态。- 对于禁用的断点,可以使用
enable
命令激活,语法格式:
-
enable [breakpoints] [num...]
-
-
- 激活用
num...
参数指定的多个断点,如果不设定num...
,表示激活所有禁用的断点 breakpoints
参数可有可无num...
:表示可以提供多个断点的编号
- 激活用
-
-
enable [breakpoints] once num…
-
-
- 临时激活以
num...
为编号的多个断点,断点只能使用 1 次,之后会自动回到禁用状态
- 临时激活以
-
-
enable [breakpoints] count num...
-
-
- 临时激活以
num...
为编号的多个断点,断点可以使用count
次,之后进入禁用状态
- 临时激活以
-
-
enable [breakpoints] delete num…
-
-
- 激活
num..
为编号的多个断点,断点只能使用 1 次,之后会被永久删除
- 激活
-
(gdb) enable
(gdb) info break
:<<!
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005a5 in main at main.c:1
breakpoint already hit 1 time
2 hw watchpoint keep y num
!
(gdb)
关注公众号 “融码一生”,领取全套 PDF / 电子书