GDB 文檔統稱三者為 breakpoint。命中斷點時,尚未執行該行代碼。GDB 以機器指令為單位執行,非源碼行,可能導致斷點位置與預期不符。
info breakpoints (或 i b) 列表欄位:
編號、類型、處置、啟用狀態、物理地址、位置(文件:行/變量)。
| 命令 | 說明 |
|---|---|
break func/line/file:line/file:func | 普通斷點,永久有效 |
tbreak ... | 臨時斷點,命中一次自動刪除 |
enable once N | 一次性斷點,命中後失效不刪除 |
rbreak regexp | 正則匹配函數名設置斷點 (grep 語法) |
break ... if (cond) | 條件斷點,如 break main if argc>1 |
cond N expr | 為現有斷點 N 添加條件;cond N 移除條件 |
條件支持 < <= == != > >= && || & | ^ >> << + - * / % 及函數調用(需返回 int)。
delete [list] 刪除指定/所有斷點clear [func/file:func/line/file:line] 刪除特定位置斷點enable/disable list 啟用/禁用ignore N count 跳過斷點 N count 次用 Class::func(int) 完整簽名區分重載。
int main() { int i=3; i=3; return 0; }
-O0: break main → 第 4 行 (i=3)
-O9: break main → 第 6 行 (return 0) // i 被優化掉
建議調試時關閉優化 (-O0)。
watch expr 寫觀察點(值被修改即停)rwatch expr 讀觀察點(值被讀取即停)awatch expr 讀寫觀察點優先使用硬件觀察點(快),不可用時退回軟件實現。
典型用法:在 main 入口斷點命中後設置 rwatch x 監視變量。
| 命令 | 縮寫 | 行為 |
|---|---|---|
| next | n | 單步跳過(不進函數) |
| step | s | 單步進入(進函數) |
| continue | c | 運行到下一斷點 |
| finish | fin | 運行完當前棧幀(step out) |
| until [loc] | u | 運行到更高地址指令(跳出循環神器) |
until 原理:循環編譯後條件判斷在體底部,until 直接跳到循環後第一條指令。
GDB 7+ 新功能:record 開始記錄,reverse-next/step/continue 反向執行。錯過關鍵點無需重啟,直接倒回去調試。
#include <stdio.h>
void foo() { printf("inside foo()"); int x=6; x+=2; }
int main() { int x=0; x+=2; foo(); printf("x=%d", x); }
錄製後可反向單步回溯 foo() 內部狀態。