用GDB除錯程式(三)

2021-06-07 21:16:29 字數 4858 閱讀 9206

四、維護停止點

上面說了如何設定程式的停止點,gdb中的停止點也就是上述的三類。在gdb中,如果你覺得已定義好的停止點沒有用了,你可以使用delete、clear、disable、enable這幾個命令來進行維護。

clear

清除所有的已定義的停止點。

clear

clear

清除所有設定在函式上的停止點。

clear

clear

清除所有設定在指定行上的停止點。

delete [breakpoints] [range...]

刪除指定的斷點,breakpoints為斷點號。如果不指定斷點號,則表示刪除所有的斷點。range 表示斷點號的範圍(如:3-7)。其簡寫命令為d。

比刪除更好的一種方法是disable停止點,disable了的停止點,gdb不會刪除,當你還需要時,enable即可,就好像**站一樣。

disable [breakpoints] [range...]

disable所指定的停止點,breakpoints為停止點號。如果什麼都不指定,表示disable所有的停止點。簡寫命令是dis.

enable [breakpoints] [range...]

enable所指定的停止點,breakpoints為停止點號。

enable [breakpoints] once range...

enable所指定的停止點一次,當程式停止後,該停止點馬上被gdb自動disable。

enable [breakpoints] delete range...

enable所指定的停止點一次,當程式停止後,該停止點馬上被gdb自動刪除。

五、停止條件維護

condition

修改斷點號為bnum的停止條件為expression。

condition

清除斷點號為bnum的停止條件。

還有乙個比較特殊的維護命令ignore,你可以指定程式執行時,忽略停止條件幾次。

ignore

表示忽略斷點號為bnum的停止條件count次。

六、為停止點設定執行命令

我們可以使用gdb提供的command命令來設定停止點的執行命令。也就是說,當執行的程式在被停止住時,我們可以讓其自動執行一些別的命令,這很有利行自動化除錯。對基於gdb的自動化除錯是乙個強大的支援。

commands [bnum]

... command-list ...

end

為斷點號bnum指寫乙個命令列表。當程式被該斷點停住時,gdb會依次執行命令列表中的命令。

例如:break foo if x>0

commands

printf "x is %d/n",x

continue

end斷點設定在函式foo中,斷點條件是x>0,如果程式被斷住後,也就是,一旦x的值在foo函式中大於0,gdb會自動列印出x的值,並繼續執行程式。

如果你要清除斷點上的命令序列,那麼只要簡單的執行一下commands命令,並直接在打個end就行了。

七、斷點選單

在c++中,可能會重複出現同乙個名字的函式若干次(函式過載),在這種情況下,break 不能告訴gdb要停在哪個函式的入口。當然,你可以使用break 也就是把函式的引數型別告訴gdb,以指定乙個函式。否則的話,gdb會給你列出乙個斷點選單供你選擇你所需要的斷點。你只要輸入你選單列表中的編號就可以了。如:

(gdb) b string::after

[0] cancel

[1] all

[2] file:string.cc; line number:867

[3] file:string.cc; line number:860

[4] file:string.cc; line number:875

[5] file:string.cc; line number:853

[6] file:string.cc; line number:846

[7] file:string.cc; line number:735

> 2 4 6

breakpoint 1 at 0xb26c: file string.cc, line 867.

breakpoint 2 at 0xb344: file string.cc, line 875.

breakpoint 3 at 0xafcc: file string.cc, line 846.

multiple breakpoints were set.

use the "delete" command to delete unwanted

breakpoints.

(gdb)

可見,gdb列出了所有after的過載函式,你可以選一下列表編號就行了。0表示放棄設定斷點,1表示所有函式都設定斷點。

八、恢復程式執行和單步除錯

當程式被停住了,你可以用continue命令恢復程式的執行直到程式結束,或下乙個斷點到來。也可以使用step或next命令單步跟蹤程式。

continue [ignore-count]

c [ignore-count]

fg [ignore-count]

恢復程式執行,直到程式結束,或是下乙個斷點到來。ignore-count表示忽略其後的斷點次數。continue,c,fg三個命令都是一樣的意思。

step

單步跟蹤,如果有函式呼叫,他會進入該函式。進入函式的前提是,此函式被編譯有debug資訊。很像vc等工具中的step in。後面可以加count也可以不加,不加表示一條條地執行,加表示執行後面的count條指令,然後再停住。

next

同樣單步跟蹤,如果有函式呼叫,他不會進入該函式。很像vc等工具中的step over。後面可以加count也可以不加,不加表示一條條地執行,加表示執行後面的count條指令,然後再停住。

set step-mode

set step-mode on

開啟step-mode模式,於是,在進行單步跟蹤時,程式不會因為沒有debug資訊而不停住。這個引數有很利於檢視機器碼。

set step-mod off

關閉step-mode模式。

finish

執行程式,直到當前函式完成返回。並列印函式返回時的堆疊位址和返回值及引數值等資訊。

until 或 u

當你厭倦了在乙個迴圈體內單步跟蹤時,這個命令可以執行程式直到退出迴圈體。

stepi 或 si

nexti 或 ni

單步跟蹤一條機器指令!一條程式**有可能由數條機器指令完成,stepi和nexti可以單步執行機器指令。與之一樣有相同功能的命令是「display/i $pc」 ,當執行完這個命令後,單步跟蹤會在打出程式**的同時打出機器指令(也就是彙編**)

九、訊號(signals)

訊號是一種軟中斷,是一種處理非同步事件的方法。一般來說,作業系統都支援許多訊號。尤其是unix,比較重要應用程式一般都會處理訊號。unix定義了許多訊號,比如sigint表示中斷字元訊號,也就是ctrl+c的訊號,sigbus表示硬體故障的訊號;sigchld表示子程序狀態改變訊號;sigkill表示終止程式執行的訊號,等等。訊號量程式設計是unix下非常重要的一種技術。

gdb有能力在你除錯程式的時候處理任何一種訊號,你可以告訴gdb需要處理哪一種訊號。你可以要求gdb收到你所指定的訊號時,馬上停住正在執行的程式,以供你進行除錯。你可以用gdb的handle命令來完成這一功能。

handle

在gdb中定義乙個訊號處理。訊號可以以sig開頭或不以sig開頭,可以用定義乙個要處理訊號的範圍(如:sigio-sigkill,表示處理從sigio訊號到sigkill的訊號,其中包括sigio,sigiot,sigkill三個訊號),也可以使用關鍵字all來標明要處理所有的訊號。一旦被除錯的程式接收到訊號,執行程式馬上會被gdb停住,以供除錯。其可以是以下幾種關鍵字的乙個或多個。

nostop

當被除錯的程式收到訊號時,gdb不會停住程式的執行,但會打出訊息告訴你收到這種訊號。

stop

當被除錯的程式收到訊號時,gdb會停住你的程式。

print

當被除錯的程式收到訊號時,gdb會顯示出一條資訊。

noprint

當被除錯的程式收到訊號時,gdb不會告訴你收到訊號的資訊。

pass

noignore

當被除錯的程式收到訊號時,gdb不處理訊號。這表示,gdb會把這個訊號交給被除錯程式會處理。

nopass

ignore

當被除錯的程式收到訊號時,gdb不會讓被除錯程式來處理這個訊號。

info signals

info handle

檢視有哪些訊號在被gdb檢測中。

十、執行緒(thread stops)

如果你程式是多執行緒的話,你可以定義你的斷點是否在所有的執行緒上,或是在某個特定的執行緒。gdb很容易幫你完成這一工作。

break thread

break thread if ...

linespec指定了斷點設定在的源程式的行號。threadno指定了執行緒的id,注意,這個id是gdb分配的,你可以通過「info threads」命令來檢視正在執行程式中的執行緒資訊。如果你不指定thread 則表示你的斷點設在所有執行緒上面。你還可以為某執行緒指定斷點條件。如:

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

當你的程式被gdb停住時,所有的執行執行緒都會被停住。這方便你你檢視執行程式的總體情況。而在你恢復程式執行時,所有的執行緒也會被恢復執行。那怕是主程序在被單步除錯時。

**:

用GDB除錯程式(三)

四 維護停止點 上面說了如何設定程式的停止點,gdb中的停止點也就是上述的三類。在gdb中,如果你覺得已定義好的停止點沒有用了,你可以使用delete clear disable enable這幾個命令來進行維護。clear 清除所有的已定義的停止點。clear clear 清除所有設定在函式上的停...

用GDB除錯程式(三)

四 維護停止點 上面說了如何設定程式的停止點,gdb中的停止點也就是上述的三類。在gdb中,如果你覺得已定義好的停止點沒有用了,你可以使用delete clear disable enable這幾個命令來進行維護。clear 清除所有的已定義的停止點。clear clear 清除所有設定在函式上的停...

用GDB除錯程式(三)

四 維護停止點 上面說了如何設定程式的停止點,gdb中的停止點也就是上述的三類。在gdb中,如果你覺得已定義好的停止點沒有用了,你可以使用delete clear disable enable這幾個命令來進行維護。clear 清除所有的已定義的停止點。clear clear 清除所有設定在函式上的停...