GDB禁用刪除斷點
GDB 調試器支持 3 種斷點,分別為普通斷點(用 break 命令創建)、觀察斷點(用 watch 命令建立)以及捕捉斷點(用 catch 命令建立)。並且如果需要的話,我們可以在被調試程序中打多個斷點,甚至於 GDB 允許在同一位置打多個斷點。如果之前建立的斷點不再需要或者暫時不需要,該如何刪除或者禁用呢?常用的方式有 2 種:
1、使用 quit 命令退出調試,然后重新對目標程序啟動調試,此方法會將消除上一次調試操作中建立的所有斷點;
2、使用專門刪除或禁用斷點的命令,既可以刪除某一個斷點,也可以刪除全部斷點。
示例代碼:
#include <stdio.h> int main(){ int num = 0; scanf("%d", &num); printf("%d", num); return 0; }
查看當前斷點
對於當前調試環境中已經建好且尚未刪除的斷點,可以通過以下 2 種方式查看它們。
1) 借助如下指令,可以查看當前調試環境中存在的所有斷點,包括普通斷點、觀察斷點以及捕捉斷點:
(gdb) info breakpoint [n] (gdb) info break [n]
參數 n 作為可選參數,為某個斷點的編號,表示查看指定斷點而非全部斷點。
要知道,任何類型的斷點在建立時,GDB 調試器都會為其分配一個獨一無二的斷點編號。以 main 為例,我們嘗試建立如下斷點:
(gdb) b 1 Breakpoint 1 at 0x1189: file main.c, line 2. (gdb) r Starting program: ~/demo/main.exe Breakpoint 1, main () at main.c:2 2 int main(){ (gdb) watch num Hardware watchpoint 2: num (gdb) catch throw int 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 0x0000555555555189 in main at main.c:2 breakpoint already hit 1 time 2 hw watchpoint keep y num 3 catchpoint keep y exception throw matching: int (gdb)
借助每個斷點不同的編號,也可以進行精准查詢:
(gdb) info break 1 Num Type Disp Enb Address What 1 breakpoint keep y 0x000000000040053c in main at main.c:2 breakpoint already hit 1 time
以上輸出信息中各列的含義分別是:斷點編號(Num)、斷點類型(Type)、是臨時斷點還是永久斷點(Disp)、目前是啟用狀態還是禁用狀態(Enb)、斷點的位置(Address)、斷點當前的狀態(作用的行號、已經命中的次數等,用 What 列表示)。
2) 除此之外,對於調試環境中已經建好且未刪除的觀察斷點,也可以使用 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 number 1.
由於當前環境中僅有 1 個觀察斷點,因此 info watchpoint 命令僅羅列了編號為 2 的觀察斷點的信息。需要注意的是,該命令僅能用於查看觀察斷點,普通斷點和捕捉斷點無法使用該命令。
GDB 刪除斷點
無論是普通斷點、觀察斷點還是捕捉斷點,都可以使用 clear 或者 delete 命令進行刪除。
1)clear 命令
clear 命令可以刪除指定位置處的所有斷點,常用的語法格式如下所示:
(gdb) clear location
參數 location 通常為某一行代碼的行號或者某個具體的函數名。當 location 參數為某個函數的函數名時,表示刪除位於該函數入口處的所有斷點。
在上面調試環境中,繼續執行如下命令:
(gdb) clear 2 (gdb) info break Deleted breakpoint 1 Num Type Disp Enb Address What 2 hw watchpoint keep y num 3 catchpoint keep y exception throw matching: int (gdb)
可以看到,斷點編號為 1、位於程序第 2 行代碼處的普通斷點已經被刪除了。
2) delete命令
delete 命令(可以縮寫為 d )通常用來刪除所有斷點,也可以刪除指定編號的各類型斷點,語法格式如下:
delete [breakpoints] [num]
其中,breakpoints 參數可有可無,num 參數為指定斷點的編號,其可以是 delete 刪除某一個斷點,而非全部。示例:
(gdb) delete 2 (gdb) info break Num Type Disp Enb Address What 3 catchpoint keep y exception throw matching: int
可以看到,delete 命令刪除了編號為 2 的觀察斷點。
如果不指定 num 參數,則 delete 命令會刪除當前程序中存在的所有斷點。例如:
(gdb) delete Delete all breakpoints? (y or n) y (gdb) info break No breakpoints or watchpoints.
GDB 禁用斷點
所謂禁用,就是使目標斷點暫時失去作用,必要時可以再將其激活,恢復斷點原有的功能。禁用斷點可以使用 disable 命令,語法格式如下:
disable [breakpoints] [num...]
breakpoints 參數可有可無;num... 表示可以有多個參數,每個參數都為要禁用斷點的編號。如果指定 num...,disable 命令會禁用指定編號的斷點;反之若不設定 num...,則 disable 會禁用當前程序中所有的斷點。
示例:
(gdb) info break Num Type Disp Enb Address What 1 breakpoint keep y 0x0000555555555189 in main at main.c:2 breakpoint already hit 1 time 2 hw watchpoint keep y num 3 catchpoint keep y exception throw matching: int (gdb) disable 1 2 (gdb) info break Num Type Disp Enb Address What 1 breakpoint keep n 0x0000555555555189 in main at main.c:2 breakpoint already hit 1 time 2 hw watchpoint keep n num 3 catchpoint keep y exception throw matching: int (gdb)
可以看到,對於用 disable 命令禁用的斷點,Enb 列用 n 表示其處於禁用狀態,用 y 表示該斷點處於激活狀態。
對於禁用的斷點,可以使用 enable 命令激活,該命令的語法格式有多種,分別對應有不同的功能:
enable [breakpoints] [num...] 激活用 num... 參數指定的多個斷點,如果不設定 num...,表示激活所有禁用的斷點 enable [breakpoints] once num… 臨時激活以 num... 為編號的多個斷點,但斷點只能使用 1 次,之后會自動回到禁用狀態 enable [breakpoints] count num... 臨時激活以 num... 為編號的多個斷點,斷點可以使用 count 次,之后進入禁用狀態 enable [breakpoints] delete num… 激活 num.. 為編號的多個斷點,但斷點只能使用 1 次,之后會被永久刪除。
其中,breakpoints 參數可有可無;num... 表示可以提供多個斷點的編號,enable 命令可以同時激活多個斷點。
仍以上面的調試環境為例,當下程序停止在第 2 行(main() 函數開頭處),此時執行如下命令:
(gdb) info break Num Type Disp Enb Address What 1 breakpoint keep n 0x0000555555555189 in main at main.c:2 breakpoint already hit 1 time 2 hw watchpoint keep n num 3 catchpoint keep y exception throw matching: int (gdb) enable delete 2 (gdb) info break Num Type Disp Enb Address What 1 breakpoint keep n 0x0000555555555189 in main at main.c:2 breakpoint already hit 1 time 2 hw watchpoint del y num 3 catchpoint keep y exception throw matching: int (gdb) c Continuing. Hardware watchpoint 2: num Old value = 32767 New value = 0 main () at main.c:4 4 scanf("%d", &num); (gdb) info break Num Type Disp Enb Address What 1 breakpoint keep n 0x0000555555555189 in main at main.c:2 breakpoint already hit 1 time 3 catchpoint keep y exception throw matching: int (gdb)
可以看到,通過借助 enable delete 命令,我們激活了編號為 2 的觀察斷點,但其只能作用 1 次,因此當繼續執行程序時,其會在程序第 4 行暫停,隨時該斷點會被刪除。