基本資訊檢視
棧資訊
不管是操作轉儲檔案還是用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