博客專欄

EEPW首頁 > 博客 > Linux編程基礎(chǔ)——GDB(設(shè)置斷點(diǎn))

Linux編程基礎(chǔ)——GDB(設(shè)置斷點(diǎn))

發(fā)布人:電子禪石 時(shí)間:2020-02-22 來源:工程師 發(fā)布文章

       

啟動(dòng)GDB后,首先就是要設(shè)置斷點(diǎn),程序中斷后才能調(diào)試。在gdb中,斷點(diǎn)通常有三種形式:

斷點(diǎn)(BreakPoint):

在代碼的指定位置中斷,這個(gè)是我們用得最多的一種。設(shè)置斷點(diǎn)的命令是break,它通常有如下方式:

  • break <function>    在進(jìn)入指定函數(shù)時(shí)停住
  • break <linenum>    在指定行號停住。
  • break +/-offset    在當(dāng)前行號的前面或后面的offset行停住。offiset為自然數(shù)。
  • break filename:linenum    在源文件filename的linenum行處停住。
  • break ... if <condition>    ...可以是上述的參數(shù),condition表示條件,在條件成立時(shí)停住。比如在循環(huán)境體中,可以設(shè)置break if i=100,表示當(dāng)i為100時(shí)停住程序。

可以通過info breakpoints [n]命令查看當(dāng)前斷點(diǎn)信息。此外,還有如下幾個(gè)配套的常用命令:

  • delete    刪除所有斷點(diǎn)
  • delete breakpoint [n]    刪除某個(gè)斷點(diǎn)
  • disable breakpoint [n]    禁用某個(gè)斷點(diǎn)
  • enable breakpoint [n]    使能某個(gè)斷點(diǎn)

觀察點(diǎn)(WatchPoint):

在變量讀、寫或變化時(shí)中斷,這類方式常用來定位bug。

  • watch <expr>    變量發(fā)生變化時(shí)中斷
  • rwatch <expr>    變量被讀時(shí)中斷
  • awatch <expr>     變量值被讀或被寫時(shí)中斷

可以通過info watchpoints [n]命令查看當(dāng)前觀察點(diǎn)信息

捕捉點(diǎn)(CatchPoint):

捕捉點(diǎn)用來補(bǔ)捉程序運(yùn)行時(shí)的一些事件。如:載入共享庫(動(dòng)態(tài)鏈接庫)、C++的異常等。通常也是用來定位bug。

捕捉點(diǎn)的命令格式是:catch <event>event可以是下面的內(nèi)容

  • throw     C++拋出的異常時(shí)中斷
  • catch     C++捕捉到的異常時(shí)中斷
  • exec    調(diào)用系統(tǒng)調(diào)用exec時(shí)(只在某些操作系統(tǒng)下有用)
  • fork    調(diào)用系統(tǒng)調(diào)用fork時(shí)(只在某些操作系統(tǒng)下有用)
  • vfork    調(diào)用系統(tǒng)調(diào)用vfork時(shí)(只在某些操作系統(tǒng)下有用)
  • load 或 load <libname>     載入共享庫時(shí)(只在某些操作系統(tǒng)下有用)
  • unload 或 unload <libname>    卸載共享庫時(shí)(只在某些操作系統(tǒng)下有用)

另外,還有一個(gè)tcatch <event>,功能類似,不過他只設(shè)置一次捕捉點(diǎn),當(dāng)程序停住以后,應(yīng)點(diǎn)被自動(dòng)刪除。

捕捉點(diǎn)信息的查看方式和代碼斷點(diǎn)的命令是一樣的,這里就不多介紹了。

在特定線程中中斷

你可以定義你的斷點(diǎn)是否在所有的線程上,或是在某個(gè)特定的線程。GDB很容易幫你完成這一工作。

  • break <linespec> thread <threadno>

  • break <linespec> thread <threadno> if ...

linespec指定了斷點(diǎn)設(shè)置在的源程序的行號。threadno指定了線程的ID,注意,這個(gè)ID是GDB分配的,你可以通過"info threads"命令來查看正在運(yùn)行程序中的線程信息。如果你不指定thread <threadno>則表示你的斷點(diǎn)設(shè)在所有線程上面。你還可以為某線程指定斷點(diǎn)條件。如:

     (gdb) break frik.c:13 thread 28 if bartab > lim

當(dāng)你的程序被GDB停住時(shí),所有的運(yùn)行線程都會被停住。這方便你你查看運(yùn)行程序的總體情況。而在你恢復(fù)程序運(yùn)行時(shí),所有的線程也會被恢復(fù)運(yùn)行。那怕是主進(jìn)程在被單步調(diào)試時(shí)。

恢復(fù)程序運(yùn)行和單步調(diào)試

在gdb中,和調(diào)試步進(jìn)相關(guān)的命令主要有如下幾條:

  • continue    繼續(xù)運(yùn)行程序直到下一個(gè)斷點(diǎn)(類似于VS里的F5)
  • next        逐過程步進(jìn),不會進(jìn)入子函數(shù)(類似VS里的F10)
  • setp        逐語句步進(jìn),會進(jìn)入子函數(shù)(類似VS里的F11)
  • until        運(yùn)行至當(dāng)前語句塊結(jié)束
  • finish    運(yùn)行至函數(shù)結(jié)束并跳出,并打印函數(shù)的返回值(類似VS的Shift+F11)

PS:這些命令大部分可以簡寫為第一個(gè)字母,在日常使用過程中,往往只會輸入第一個(gè)字符即可執(zhí)行該命令,我標(biāo)紅的即是通常的使用方式。這幾條命令使用非常頻繁,并且可以帶一些附加參數(shù)以實(shí)現(xiàn)高級功能,需要熟練掌握。


*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請聯(lián)系工作人員刪除。



關(guān)鍵詞:

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉