gdb 常用命令

Deconx發表於2022-03-12

基本資訊檢視

棧資訊

不管是操作轉儲檔案還是用GDB設定斷點進行除錯,都可以輸入 (gdb)bt 列印棧內容進行檢視。一般的當機BUG,看下當機的位置,然後看下原始碼基本就可以解決了。但是很多情況下簡單的 (gdb)bt 還查不到問題,這時候就要涉及到比較複雜的操作。下面羅列了一些對棧的操作:

  • (gdb) bt:顯示所有棧幀
  • (gdb) bt 10:顯示前面10個棧幀
  • (gdb) bt -10:顯示後面10個棧幀
  • (gdb) bt full:顯示棧幀以及區域性變數
  • (gdb) bt full 10:顯示前面10個棧幀以及區域性變數
  • (gdb) bt full -10:顯示後面10個棧幀以及區域性變數
  • (gdb) frame <棧幀編號>:進入指定的棧幀中,然後可以檢視當前棧幀中的區域性變數,以及棧幀內容等資訊
  • (gdb) info frame <棧幀編號>:可以檢視指定棧幀的詳細資訊
  • (gdb) up:進入上層棧幀
  • (gdb) down:進入下層棧幀

變數

除錯BUG過程中檢視變數資訊是很有幫助的操作,檢視方式如下:

  • (gdb) p <變數名>

暫存器

對於除錯來說暫存器中的值也很重要,可以檢視到當前正在執行的指令的地址等。具體操作羅列如下:

  • (gdb) info reg:顯示所有暫存器。可以簡寫為:i r。如果要檢視具體的暫存器可以這樣:i $ebx
  • (gdb) p $eax:顯示eax暫存器內容
  • (gdb) p/c $eax:用字元顯示eax暫存器內容,反斜槓後面的是顯示格式,可使用的格式見下表:該表在顯示記憶體內容的x命令中也是通用的
格式 說明
x 顯示為十六進位制數
d 顯示為十進位制數
u 顯示位為符號十進位制數
o 顯示為八進位制數
t 顯示為二進位制數
a 顯示為地址
c 顯示為字元(ASCII)
f 顯示為浮點數
s 顯示為字串
i 顯示為機器語言(僅在顯示記憶體的x命令中可用)

記憶體

可以檢視具體記憶體地址中的內容,比如:目前執行的彙編指令,以及棧中的內容等。

  • (gdb) x $pc:顯示程式指標指向位置的內容
  • (gdb) x/i $pc:顯示程式當前位置的彙編指令
  • (gdb) x/10i $pc:顯示程式當前位置開始往後的10條彙編指令
  • (gdb) disas $pc:反彙編當前函式

除錯

斷點:

除錯程式中,設定斷點進行除錯是最方便有效的手段,因此學會如果靈活設定斷點是除錯的基本功。

設定斷點
  • (gdb) break <函式名>:對當前正在執行的檔案中的指定函式設定斷點。可簡寫為:(gdb) b <函式名>
  • (gdb) break <行號>:對當前正在執行的檔案中的特定行設定斷點。可簡寫為:(gdb) b <行號>
  • (gdb) break <檔名:行號>:對指定檔案的指定行設定斷點。最常用的設定斷點方式。可簡寫為:(gdb) b <檔名:行號>
  • (gdb) break <檔名:函式名>:對指定檔案的指定函式設定斷點。C++類中的方法似乎不好使。可簡寫為:(gdb) b <檔名:函式名>
  • (gdb) break <+/-偏移量>:當前指令行+/-偏移量出設定斷點。可簡寫為:b <+/-偏移量>
  • (gdb) break <*地址>:指定地址處設定斷點。可簡寫為:b <*地址>
檢視、刪除斷點
  • (gdb) info break:顯示所有斷點以及監視點。可簡寫為:(gdb) i b
  • (gdb) delete <編號>:刪除編號指向的斷電或者監視點。可簡寫為:(gdb) d <編號>
  • (gdb) clear <行號>:刪除該行的斷點
  • (gdb) clear <檔案號:行號>:刪除該行的斷點
設定無效、有效斷點
  • (gdb) disble <斷電編號>:當前斷點設定為無效
  • (gdb) enable:當前斷點設定為有效

監視點

可以監視某個變數,在變數被訪問或者被修改時程式會在當前點進入斷點。刪除,檢視監視點的方式與斷點相同。設定監視點方式如下:

  • (gdb) watch <表示式>:表示式發生變化時暫停
  • (gdb) awatch <表示式>:表示式訪問或者改變時暫停
  • (gdb) rwatch <表示式>:表示式被訪問時暫停

條件斷點

在除錯程式過程中,有時候我們只想在某個條件下停止程式,然後進行單步除錯,而條件斷點就是為此而設計。下面是條件斷點的操作方式:

  • (gdb) b <斷點> if <條件表示式> : 例如:b main.cpp:8 if x=10 && y=10
  • (gdb) condition <斷點編號>:刪除該斷點的條件。
  • (gdb) condition <斷點編號> <條件表示式>:修改斷點條件。例如:condition 1 x=10 && y=10

斷點命令

每次斷點發生時候,想要檢視的變數很多時,如果每個變數都手動print則需要浪費很多時間。斷點命令可以在斷點發生時批量執行GDB命令。下面是斷點命令的設定方式:

  • (gdb) commands <斷點編號>

  • (gdb) >print x

  • (gdb) >print y

  • (gdb) >end

    首先輸入GDB命令commands <斷點編號>然後回車,這時候會出現>提示符。出現>提示符後可以輸入斷點發生時需要執行的GDB命令,每行一條,全部輸入完成後輸入end結束斷點命令。

反覆執行

單步執行時如果進入了你不關心的函式,你想立即跳出函式;或者進入了大迴圈中,你想立即迴圈。下面的命令可以幫到你:

  • (gdb) ignore <斷點編號> <次數>:忽略N次斷點
  • (gdb) c N: 執行N次指令,會忽略斷點
  • (gdb) s/stepi/n/nexti N:往後執行N行,不會忽略斷點
  • (gdb) finish:執行完當前函式後停止,不會忽略斷點
  • (gdb) until:執行完當前迴圈後停止,不會忽略斷點
  • (gdb) until <地址>:執行到指定地址停止

設定變數值

對變數的值進行控制,可以更快的除錯自己的程式。下面就是設定變數值的方法:

  • (gdb) set variable <變數> = <表示式>:將變數的值設定為指定表示式的值。例如 set variable x=10

手動生成轉儲檔案

  • (gdb) generate-core-file 簡寫為:(gdb) gcore