使用gdb調試多進程與多線程程序


高能預警


本文主要介紹瞭如何使用linux環境下的代碼調試工具—gdb來調試多進程與多線程程序,主要內容有

1. 問題引入
2. 調試方法介紹及代碼實例
3. gdb常用命令總結
4. 一些大神們關於此主題的介紹並附鏈接

——>全篇閱讀(不包括鏈接)大概需要8min<——

讀完本文後,你可以用簡單的方法調試多線程多進程程序。對幾種調試方法也會有一種宏觀認識。


問題引入


先來看一張圖:

1

圖中,Proc1通過調用fork函數產生子進程 Proc2,Proc2 又再次調用它產生子進程Proc3。這顯然是一個多進程程序。

但是,默認設置下,GDB不支持多進程程序調試。在調試多進程程序時GDB只會調試主進程,即proc1。例如,使用GDB調試某個進程,如果該進程fork了子進程,GDB會繼續調試該進程,子進程會不受干擾地運行下去。

注:GDB默認支持調試多線程

那麼問題來了,如何使用 GDB 調試子進程 proc2 或者 proc3 呢?

這就是本博文要講的主題。


方法介紹及代碼實例


總的來說,用gdb調試多進程與多線程有3種方法。

Solution1:follow-fork-mode

首先,這種方法對linux環境是有限制的:

在2.5.60版Linux內核及以後,GDB7.0版本以上的linux環境對使用fork/vfork創建子進程的程序提供了follow-fork-mode選項來支持多進程調試。

首先認識兩個選項:

follow-fork-mode(同步進程模式):這個模式有兩個選項:parent和child。默認值爲parent
detach-on-fork(分離進程):這個模式也有兩個選項:on和off 。默認值爲on

下面是他們各個選項組合所代表的含義:

2

從3和4可以看出,改變兩個選項設置調試多進程,實際上只是從宏觀上實現。同一時刻gdb只能操作一個進程,另一個進程只能被阻塞。

接下來通過代碼來看看選項的設置方法和具體的調試過程。

首先調試多進程:

Step1:查看是否達到環境要求

內核版本:
1
GDB版本:
3

可以看到,環境達到要求,所以可以進行操作。

Step2:編寫多進程代碼

首先看看fork函數的原型及返回值介紹:

4

編寫代碼:

5

運行代碼確保代碼編寫無誤:

8

Step3:開始調試

然後調試多線程

Step1:編寫代碼

10

運行代碼保證代碼編寫無誤:

6

Solution2:Attach子進程

Solution3:GDB wrapper

很多時候,父進程 fork 出子進程,子進程會緊接着調用 exec族函數進行程序替換來執行新的代碼。對於這種情況,我們也可以使用gdb wrapper 方法。它的優點是不用添加額外代碼。

其基本原理是以gdb調用待執行代碼作爲一個新的整體來被exec函數執行,使得待執行代碼始終處於gdb的控制中,這樣我們自然能夠調試該子進程代碼。

這種方法可以參考文末的大神鏈接,博主技術太low,還不會實現。。。

小結

上述三種方法各有優缺點,因此適應於不同的場合和環境:

1.follow-fork-mode方法:方便易用,對系統內核和GDB版本有限制,適合於較爲簡單的多進程與多線程系統

2.attach子進程方法:靈活強大,但需要添加額外代碼,適合於各種複雜情況,特別是守護進程

3.GDB wrapper方法:專用於fork+exec模式,不用添加額外代碼,但需要X環境支持(xterm/VNC)


gdb常用命令總結


請移步:陳皓大神gdb調試系列


大神鏈接


1.3種方法綜合講解

IBM:使用 GDB 調試多進程程序

百度文庫:多進程 多線程調試方法 GDB調試 .

2.法1講解:

高科大神:gdb調試多進程和多線程命令

CSDN:Linux多進程和多線程的一次gdb調試實例

百度:GDB調試-多進程與多線程程序

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章