GDB 的 七個單步調(diào)試命令

調(diào)試器 是一個可以運(yùn)行你的代碼并檢查問題的軟件。??GNU Debugger???(GBD)是最流行的調(diào)試器之一,在這篇文章中,我研究了 GDB 的 ??step??? 命令和其他幾種常見情況的相關(guān)命令。??step?? 是一個被廣泛使用的命令,但它有一些人們不太了解的地方,可能會使得他們十分困惑。此外,還有一些方法可以在不使用 ??step??? 命令的情況下進(jìn)入一個函數(shù),比如使用不太知名的 ??advance?? 命令。
1、無調(diào)試符號
考慮以下這個簡單的示例程序:
如果你在沒有 調(diào)試符號debugging sysbols 的情況下進(jìn)行編譯(LCTT 譯注:即在使用 ??gcc?? 編譯程序時沒有寫 ??-g?? 選項(xiàng)),然后在 ??bar?? 上設(shè)置一個斷點(diǎn),然后嘗試在這個函數(shù)內(nèi)使用 ??step?? 來單步執(zhí)行語句。GDB 會給出一個 沒有行號信息no line number information
2、stepi 命令
但是你仍然可以在沒有行號信息的函數(shù)內(nèi)部單步執(zhí)行語句,但要使用 ??stepi?? 命令來代替 ??step??。??stepi?? 一次只執(zhí)行一條指令。當(dāng)使用 GDB 的 ??stepi?? 命令時,先做 ??display/i $pc?? 通常很有用,這會在每一步之后顯示 程序計(jì)數(shù)器program counter 的值和相應(yīng)的 機(jī)器指令machine instruction:
在上述的 ??display?? 命令中,??i?? 代表機(jī)器指令,??$pc?? 表示程序計(jì)數(shù)器寄存器(即 PC 寄存器)。
使用 ??info registers?? 命令,來打印寄存器的內(nèi)容,也是十分有用的。
3、復(fù)雜的函數(shù)調(diào)用
在帶調(diào)試符號的 ??-g?? 選項(xiàng),重新編譯示例程序后,你可以使用行號在 ??main?? 中 ??bar?? 調(diào)用上設(shè)置斷點(diǎn),然后再單步執(zhí)行 ??bar?? 函數(shù)的語句:
接下來,用 ??step??,來單步執(zhí)行 ??bar()?? 函數(shù)的語句:
函數(shù)調(diào)用的參數(shù)需要在實(shí)際的函數(shù)調(diào)用之前進(jìn)行處理,??bar()?? 函數(shù)的參數(shù)是 ??num()?? 函數(shù),所以 ??num()?? 會在 ??bar()?? 被調(diào)用之前執(zhí)行。但是,通過 GDB 調(diào)試,你怎么才能如愿以償?shù)剡M(jìn)入 ??bar()?? 函數(shù)呢?你可以使用 ??finish?? 命令,并再次使用 ??step?? 命令。
4、tbreak 命令
??tbreak?? 命令會設(shè)置一個臨時斷點(diǎn)。如果你不想設(shè)置永久斷點(diǎn),那么這個命令是很有用的。舉個例子??,你想進(jìn)入一個復(fù)雜的函數(shù)調(diào)用,例如 ??f(g(h()), i(j()), ...)??,在這種情況下,你需要一個很長的 ??step/finish/step?? 序列,才能到達(dá) ??f?? 函數(shù)。如果你設(shè)置一個臨時斷點(diǎn),然后再使用 ??continue?? 命令,這樣就不需要以上的序列了。為了證明這一點(diǎn),你需要像以前一樣將斷點(diǎn)設(shè)置在 ??main?? 的 ??bar?? 調(diào)用上。然后在 ??bar?? 上設(shè)置臨時斷點(diǎn)。當(dāng)?shù)竭_(dá)該臨時斷點(diǎn)后,臨時斷點(diǎn)會被自動刪除。
在調(diào)用 ??bar?? 的時候遇到斷點(diǎn),并在 ??bar?? 上設(shè)置臨時斷點(diǎn)后,你只需要使用 ??continue?? 繼續(xù)運(yùn)行直到 ??bar?? 結(jié)束。
5、disable 命令
類似地,你也可以在 ??bar?? 上設(shè)置一個正常的斷點(diǎn),然后執(zhí)行 ??continue??,然后在不再需要第二個斷點(diǎn)時,使用 ??disable?? 命令禁用這個斷點(diǎn),這樣也能達(dá)到與 ??tbreak?? 相同的效果。
正如你所看到的,??info breakpoints?? 命令在 ??Enb?? 列下顯示為 ??n??,這意味著這個斷點(diǎn)已被禁用。但你也能在再次需要這個斷點(diǎn)時,再啟用它。
6、advance 命令運(yùn)行程序到指定的位置
另一個進(jìn)入函數(shù)內(nèi)部的方法是 ??advance?? 命令。你可以簡單地用 ??advance bar??,來代替 ??tbreak bar ; continue??。這一命令會將程序繼續(xù)運(yùn)行到指定的位置。
??advance?? 命令的一個很棒的地方在于:如果程序并沒有到達(dá)你試圖進(jìn)入的位置,那么 GDB 將在當(dāng)前函數(shù)運(yùn)行完成后停止。因此,程序的執(zhí)行會受到限制:
7、skip 命令
進(jìn)入 ??bar?? 函數(shù)的另一種方式是使用 ??skip num?? 命令:
請使用 ??info skip?? 命令,來了解 GDB 跳過了哪些函數(shù)。??num()?? 函數(shù)被標(biāo)記為 ??y??,表示跳過了 ??num()?? 函數(shù):
如果不再需要 ??skip??,可以禁用(并稍后重新啟用)或完全刪除它。你可以添加另一個 ??skip??,并禁用第一個 ??skip??,然后全部刪除。要禁用某個 ??skip??,必須指定其編號(例如,??skip disable 1??),如果沒有指定,則會禁用所有的 ??skip??。啟用或刪除 ??skip?? 的工作原理相同:
GDB 的 step 命令
使用 GDB 的 ??step?? 命令是調(diào)試程序的一個有用工具。即使是復(fù)雜的函數(shù),也有幾種方法可以單步調(diào)試這些函數(shù),所以下次你在排除代碼問題的時候,可以嘗試一下這些 GDB 技術(shù)。















 
 
 







 
 
 
 