GDB常用除錯命令以及多程序多執行緒除錯

2021-08-18 02:09:06 字數 3345 閱讀 4741

今天把所有的gdb常用的除錯命令都過了一遍,尤其是多執行緒除錯。所以先做個總結,以免忘記。以後如果有新的有用的命令會繼續追加。

執行命令。

打斷點,使用方法:

對於break命令,我們要靈活使用。例如打多個斷點。多執行緒程式中我們可以主函式中線程建立後立即打斷點,執行執行緒函式入口打斷點等。

關閉斷點:delete(d) [breakpoints num] [range...]

顯示斷點:info breakpoints顯示所有斷點

普通用法就不說了。

當程式被停住之後,可以使用continue(c)命令,恢復程式的執行直到程式結束,或到達下乙個斷點。

這裡要注意如果沒有斷點程式是會直接結束的。

這個命令比較常用,用來檢視我們想看的內容。比如有關陣列可以看全部,也可以看從左到右某一部分:

print命令針對變數檢視的輸出格式有:

這個命令比較有用。watch一般用來觀察某個表示式(變數也是一種表示式)的值是否有變化,如果有變化,馬上停住程式。我們有一下幾種方法設定觀察點:

舉例如下,演示觀測*i的值,一旦變化停下來:

在迴圈中我們也可以使用watch,配合ignore,它是除了until命令之外又乙個可以讓我們跳出迴圈的方法,不過watch+ignore更強大,可以任意跳轉到第i次迴圈。它們的意思就是觀察乙個變數,可以理解為斷點,ignore這個斷點多少次,然後用continue就可以直接跳過了。

使用該命令來檢視記憶體位址中的值。語法是:x/u addr 

addr表示乙個記憶體位址。「x/」後的n、f、u都是可選的引數,n 是乙個正整數,表示顯示記憶體的長度,也就是說從當前位址向後顯示幾個位址的內容;f 表示顯示的格式,如果位址所指的是字串,那麼格式可以是s,如果位址是指令位址,那麼格式可以是i;u 表示從當前位址往後請求的位元組數,如果不指定的話,gdb預設是4位元組。u引數可以被一些字元代替:b表示單位元組,h表示雙位元組,w表示四位元組,g表示八字節。當我們指定了位元組長度後,gdb會從指定的記憶體位址開始,讀寫指定位元組,並把其當作乙個值取出來。n、f、u這3個引數可以一起使用,例如命令「x/3uh 0x54320」表示從記憶體位址0x54320開始以雙位元組為1個單位(h)、16進製制方式(u)顯示3個單位(3)的記憶體。

jump命令不會改變程式棧的內容,一般只在同一函式內跳轉。

使用signal 訊號名(如sigint)這種方式把訊號傳送給程式,如果程式註冊了signal_handler函式,還可以進行相應的處理,幫助除錯程式。

強制呼叫某函式,它會顯示函式返回值(如果函式返回值不是void)。print命令也可以完成該功能。

反彙編命令,檢視執行時源**的機器碼。

我們可以先執行程式,然後再另一終端使用ps -ef | grep "main"(main此處是可執行檔名)搜尋到子程序pid,然後啟動gdb,在將其附加(attach)到gdb偵錯程式上。

我們知道如果不設定任何選項,gdb預設除錯父程序。偵錯程式選項用法如下:

預設設定下,在除錯多程序程式時gdb只會除錯主程序。但是gdb(>v7.0)支援多程序的分別以及同時除錯,換句話說,gdb可以同時除錯多個程式。只需要設定follow-fork-mode(預設值:parent)和detach-on-fork(預設值:on)即可。我們還可以使用catch fork指令,如果fork異常,會停止程式。

follow-fork-mode  detach-on-fork   說明

parent                     on               只除錯主程序(gdb預設)

child                        on               只除錯子程序

parent                     off               同時除錯兩個程序,gdb跟主程序,子程序block在fork位置

child                        off               同時除錯兩個程序,gdb跟子程序,主程序block在fork位置

設定方法:set follow-fork-mode [parent|child]   set detach-on-fork [on|off]

gdb除錯一般有兩種模式:all-stop模式和no-stop模式(gdb7.0之前不支援no-stop模式)。

1.all-stop模式

在這種模式下,

當你的程式在gdb由於任何原因而停止,所有的執行緒都會停止,而不僅僅是當前的執行緒。一般來說,gdb不能單步所有的執行緒。因為執行緒排程是gdb無法控制的。

無論什麼時候當gdb停止你的程式,它都會自動切換到觸發斷點的那個執行緒

。2.no-stop模式(網路程式設計常用)

顧名思義,啟動不關模式。當程式在gdb中停止,

只有當前的執行緒會被停止,而其他執行緒將會繼續執行

。這時候step,next這些命令就只對當前執行緒起作用。

如果需要開啟no-stop模式,可以向~/.gdbinit新增配置檔案:

[python]view plain

copy

#enable the async inte***ce

set target-async 1

#if using the cli, pagination breaks non-stop

set pagination off  

#finall, turn it on

set non-stop on  

gdb支援的命裡有兩種型別:前台的(同步的)和後台(非同步 )的。區別很簡單,同步的在輸出提示符之前會等待程式report一些執行緒已經終止的資訊,非同步則是直接返回。所以我們需要set target-async 1。set pagination off不要出現 type to continue 的提示資訊 。最後一步是開啟。

下面是常用命令:

主要是我們要用能用的上的,比如no-stop模式,一般多執行緒除錯就很有用的。

參考:

GDB常用除錯命令以及多程序多執行緒除錯

今天把所有的gdb常用的除錯命令都過了一遍,尤其是多執行緒除錯。所以先做個總結,以免忘記。以後如果有新的有用的命令會繼續追加。執行命令。打斷點,使用方法 對於break命令,我們要靈活使用。例如打多個斷點。多執行緒程式中我們可以主函式中線程建立後立即打斷點,執行執行緒函式入口打斷點等。關閉斷點 de...

gdb多程序除錯

使用gdb最好的文件就是其名為 debugging with gdb 的參考手冊。手冊中有一小章節提到了如何除錯多程序程式。一般情況下,如果被gdb除錯的程式中呼叫fork派生出乙個新的子程序,這時gdb除錯的仍然還是父程序,其子程序的執行不被理會。如果之前你在子程序的執行routine上設定了斷點...

gdb除錯多程序

在大多數系統,gdb對使用fork建立的程序沒有進行特別的支援。當父程序使用fork建立子程序,gdb仍然只會除錯父程序,而子程序沒有得到控制和除錯。這個時候,如果你在子程序執行到的 中設定了斷點,那麼當子程序執行到這個斷點的時候,會產生乙個sigtrap的訊號,如果沒有對此訊號進行捕捉處理,就會按...