啟動GDB后,首先就是要設(shè)置斷點,程序中斷后才能調(diào)試。在gdb中,斷點通常有三種形式:
斷點(BreakPoint):
在代碼的指定位置中斷,這個是我們用得最多的一種。設(shè)置斷點的命令是break,它通常有如下方式:
- break <function> 在進入指定函數(shù)時停住
- break <linenum> 在指定行號停住。
- break +/-offset 在當(dāng)前行號的前面或后面的offset行停住。offiset為自然數(shù)。
- break filename:linenum 在源文件filename的linenum行處停住。
- break ... if <condition> ...可以是上述的參數(shù),condition表示條件,在條件成立時停住。比如在循環(huán)境體中,可以設(shè)置break if i=100,表示當(dāng)i為100時停住程序。
可以通過info breakpoints [n]命令查看當(dāng)前斷點信息。此外,還有如下幾個配套的常用命令:
- delete 刪除所有斷點
- delete breakpoint [n] 刪除某個斷點
- disable breakpoint [n] 禁用某個斷點
- enable breakpoint [n] 使能某個斷點
觀察點(WatchPoint):
在變量讀、寫或變化時中斷,這類方式常用來定位bug。
- watch <expr> 變量發(fā)生變化時中斷
- rwatch <expr> 變量被讀時中斷
- awatch <expr> 變量值被讀或被寫時中斷
可以通過info watchpoints [n]命令查看當(dāng)前觀察點信息
捕捉點(CatchPoint):
捕捉點用來補捉程序運行時的一些事件。如:載入共享庫(動態(tài)鏈接庫)、C++的異常等。通常也是用來定位bug。
捕捉點的命令格式是:catch <event>,event可以是下面的內(nèi)容
- throw C++拋出的異常時中斷
- catch C++捕捉到的異常時中斷
- exec 調(diào)用系統(tǒng)調(diào)用exec時(只在某些操作系統(tǒng)下有用)
- fork 調(diào)用系統(tǒng)調(diào)用fork時(只在某些操作系統(tǒng)下有用)
- vfork 調(diào)用系統(tǒng)調(diào)用vfork時(只在某些操作系統(tǒng)下有用)
- load 或 load <libname> 載入共享庫時(只在某些操作系統(tǒng)下有用)
- unload 或 unload <libname> 卸載共享庫時(只在某些操作系統(tǒng)下有用)
另外,還有一個tcatch <event>,功能類似,不過他只設(shè)置一次捕捉點,當(dāng)程序停住以后,應(yīng)點被自動刪除。
捕捉點信息的查看方式和代碼斷點的命令是一樣的,這里就不多介紹了。
在特定線程中中斷
你可以定義你的斷點是否在所有的線程上,或是在某個特定的線程。GDB很容易幫你完成這一工作。
break <linespec> thread <threadno>
break <linespec> thread <threadno> if ...
linespec指定了斷點設(shè)置在的源程序的行號。threadno指定了線程的ID,注意,這個ID是GDB分配的,你可以通過"info threads"命令來查看正在運行程序中的線程信息。如果你不指定thread <threadno>則表示你的斷點設(shè)在所有線程上面。你還可以為某線程指定斷點條件。如:
(gdb) break frik.c:13 thread 28 if bartab > lim
當(dāng)你的程序被GDB停住時,所有的運行線程都會被停住。這方便你你查看運行程序的總體情況。而在你恢復(fù)程序運行時,所有的線程也會被恢復(fù)運行。那怕是主進程在被單步調(diào)試時。
恢復(fù)程序運行和單步調(diào)試
在gdb中,和調(diào)試步進相關(guān)的命令主要有如下幾條:
- continue 繼續(xù)運行程序直到下一個斷點(類似于VS里的F5)
- next 逐過程步進,不會進入子函數(shù)(類似VS里的F10)
- setp 逐語句步進,會進入子函數(shù)(類似VS里的F11)
- until 運行至當(dāng)前語句塊結(jié)束
- finish 運行至函數(shù)結(jié)束并跳出,并打印函數(shù)的返回值(類似VS的Shift+F11)
PS:這些命令大部分可以簡寫為第一個字母,在日常使用過程中,往往只會輸入第一個字符即可執(zhí)行該命令,我標(biāo)紅的即是通常的使用方式。這幾條命令使用非常頻繁,并且可以帶一些附加參數(shù)以實現(xiàn)高級功能,需要熟練掌握。