gdb多線程/多進程(守護進程)調試

 

一 調試多進程

1) follow-fork-mode :

 

set follow-fork-mode [parent|child]

  • parent: fork之後繼續調試父進程,子進程不受影響。
  • child: fork之後調試子進程,父進程不受影響。

 

在使用如下方法設置完要調試的程序後:

 

  1. gdb命令行的 –-args 參數
  2. gdb環境中 set args命令。
  3. gdb --pid=PID(ps -ef | grep your_prog)

 

如果需要調試子進程,在啓動gdb後:

 

(gdb) set follow-fork-mode child

 

並在子進程代碼設置斷點。

此外還有detach-on-fork參數,指示GDB在fork之後是否斷開(detach)某個進程的調試,或者都交由GDB控制:

set detach-on-fork [on|off]

  • on: 斷開調試follow-fork-mode指定的進程。
  • off: gdb將控制父進程和子進程。follow-fork-mode指定的進程將被調試,另一個進程置於暫停(suspended)狀態。

由於follow-fork-mode的調試必然是從父進程開始的,對於fork多次,調試起來並不方便。

2) attach調試:

GDB有附着(attach)到正在運行的進程的功能,即attach <pid>命令。因此可以利用該命令attach到子進程然後進行調試。通過ps和pstree可以查看到所要調試的子進程pid。

問題是,子進程一直在運行,attach上去後都不知道運行到哪裏了。一個辦法是,在要調試的子進程初始代碼中,加入一段特殊代碼,使子進程在某個條件成立時便循環睡眠等待,attach到進程後在該代碼段後設上斷點,再把成立的條件取消,使代碼可以繼續執行下去。

Attach進程方法還是很方便的,它能夠應付各種各樣複雜的進程系統,比如孫子/曾孫進程,比如守護進程(daemon process),唯一需要的就是加入一小段代碼。適合於各種複雜情況,特別是守護進程

3) gdb wrapper:

專用於fork+exec模式,不用添加額外代碼,但需要X環境支持(xterm/VNC)。

可參考:http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/index.html

二 調試多進程

GDB多線程調試的基本命令:

  1. info threads 查看當前進程的線程。
  2. thread <ID> 切換調試的線程爲指定ID的線程。
  3. break [LOCATION] [thread THREADNUM] [if CONDITION]  在[LOCATION]處爲[thread THREADNUM]設置斷點在滿足條件[if CONDITION]時停住 。
  4. thread apply ID1 ID2 command 讓一個或者多個線程執行GDB命令command。 
  5. thread apply all command  讓所有被調試線程執行GDB命令command。 
  6. set scheduler-locking off|on|step,這個是問得最多的。在使用step或者continue命令調試當前被調試線程的時候,其他線程也是同時執行的,怎麼只讓被調試程序執行呢?通過這個命令就可以實現這個需求。 
  • off 不鎖定任何線程,也就是所有線程都執行,這是默認值。
  • on 只有當前被調試程序會執行。
  • step 在單步的時候,除了next過一個函數的情況(熟悉情況的人可能知道,這其實是一個設置斷點然後continue的行爲)以外,只有當前線程會執行。

other:

gdb中的變量以$開頭,比如你想打印一個數組中的個個元素,你可以這樣:

 
(gdb) set $i = 0
(gdb) p a[$i++]

調試宏:在GCC編譯程序的時候,加上-ggdb3參數,就可以了
  • info macro – 你可以查看這個宏在哪些文件裏被引用了,以及宏定義是什麼樣的。
  • macro – 你可以查看宏展開的樣子。
x命令是用來查看內存的,在gdb中 “help x” 你可以查看其幫助。
  • x/x 以十六進制輸出
  • x/d 以十進制輸出
  • x/c 以單字符輸出
  • x/i  反彙編 – 通常,我們會使用 x/10i $ip-20 來查看當前的彙編($ip是指令寄存器)
  • x/s 以字符串輸出
command命令,其就是把一組gdb的命令打包,有點像字處理軟件的“宏”。
(gdb) command 1
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>print arg1
>print arg2
>print arg3
>end
(gdb)
參考:

http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/index.html

http://coolshell.cn/articles/3643.html

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