使用gdb最好的文件就是其名為'
debugging with gdb
'的參考手冊。手冊中有一小章節提到了如何除錯多程序程式。一般情況下,如果被gdb除錯的程式中呼叫fork派生出乙個新的子程序,這時gdb除錯的仍然還是父程序,其子程序的執行不被理會。如果之前你在子程序的執行routine上設定了斷點,那麼當子程序執行到那個斷點時,子程序會因為收到乙個sigtrap訊號而自行終止,除非你在子程序中攔截了該訊號。
那麼使用gdb該如何除錯多程序程式呢?在其參考手冊中提供了一種通用方法,這裡說說(gdb在某些平台上如hp-ux,還提供了更簡便的方法,不過不具備通用性,這裡不說):
[測試程式]
我們先看看我們的測試程式:
/* in eg1.c */
int wib(int no1, int no2)
int main()
else if (pid == 0)
printf("%d wibed by %d equals %d/n", value, div, total);
exit(0);
} else
}該測試程式中子程序執行過程中會在wib函式中出現乙個'除0'異常。現在我們就要除錯該子程序。
[除錯原理]
不知道大家發現沒有,在(!)處在我們的測試程式在父程序fork後,子程序呼叫sleep睡了60秒。這就是關鍵,這個sleep本來是不該存在於子程序**中的,而是而了使用gdb除錯後加入的,它是我們除錯的乙個關鍵點。為什麼要讓子程序剛剛執行就開始sleep呢?因為我們要在子程序睡眠期間,利用shell命令獲取其process id,然後再利用gdb除錯外部程序的方法attach到該process id上,除錯該程序。
[除錯過程]
我覺上面的除錯原理的思路已經很清晰了,剩下的就是如何操作的問題了。我們來實踐一次吧!
我所使用的環境是solaris os 9.0/gcc 3.2/gdb 6.1。
gdb除錯程式的前提條件就是你編譯程式時必須加入除錯符號資訊,即使用'-g'編譯選項。首先編譯我們的源程式'gcc -g -o eg1 eg1.c'。編譯好之後,我們就有了我們的除錯目標eg1。由於我們在除錯過程中需要多個工具配合,所以你最好多開啟幾個終端視窗,另外一點需要注意的是最好在eg1的working directory下執行gdb程式,否則gdb回提示'no symbol table is loaded'。你還得手工load symbol table。好了,下面我們就'按部就班'的開始除錯我們的eg1。
執行eg1:
eg1 & --- 讓eg1後台執行吧。
查詢程序id:
ps -fu your_user_name
執行gdb:
gdb(gdb) attach ***xx --- ***xx為利用ps命令獲得的子程序process id
(gdb) stop --- 這點很重要,你需要先暫停那個子程序,然後設定一些斷點和一些watch
(gdb) break 37 -- 在result = wib(value, div);這行設定乙個斷點,可以使用list命令察看源**
breakpoint 1 at 0x10808: file eg1.c, line 37.
(gdb) continue
continuing.
breakpoint 1, main () at eg1.c:37
37 result = wib(value, div);
(gdb) step
wib (no1=10, no2=6) at eg1.c:13
13 diff = no1 - no2;
(gdb) continue
continuing.
breakpoint 1, main () at eg1.c:37
37 result = wib(value, div);
(gdb) step
wib (no1=9, no2=7) at eg1.c:13
13 diff = no1 - no2;
(gdb) continue
continuing.
breakpoint 1, main () at eg1.c:37
37 result = wib(value, div);
(gdb) step
wib (no1=8, no2=8) at eg1.c:13
13 diff = no1 - no2;
(gdb) next
14 result = no1 / diff;
(gdb) print diff
$6 = 0 ------- 除數為0,我們找到罪魁禍首了。
(gdb) next
program received signal sigfpe, arithmetic exception.
0xff29d830 in .div () from /usr/lib/libc.so.1
至此,我們除錯完畢。
上面僅僅是乙個簡單的多程序程式,在我們平時開發的多程序程式遠遠比這個複雜,但是除錯基本原理是不變,有一些技巧則需要我們在實踐中慢慢摸索
gdb除錯多程序
在大多數系統,gdb對使用fork建立的程序沒有進行特別的支援。當父程序使用fork建立子程序,gdb仍然只會除錯父程序,而子程序沒有得到控制和除錯。這個時候,如果你在子程序執行到的 中設定了斷點,那麼當子程序執行到這個斷點的時候,會產生乙個sigtrap的訊號,如果沒有對此訊號進行捕捉處理,就會按...
gdb除錯多程序
gdb 是 linux 系統上常用的 c c 除錯工具,功能十分強大。對於較為複雜的系統,比如多程序系統,如何使用 gdb 除錯呢?實際上,gdb 沒有對多程序程式除錯提供直接支援。例如,使用gdb除錯某個程序,如果該程序fork了子程序,gdb會繼續除錯該程序,子程序會不受干擾地執行下去。如果你事...
GDB多程序除錯
使用 gdb 除錯的時候,gdb 預設只能跟蹤乙個程序,可以在 fork 函式呼叫之前,通過指令設定 gdb 除錯工具跟蹤父程序或者是跟蹤子程序,預設跟蹤父程序。設定除錯父程序或者子程序 set follow fork mode parent 預設 child 設定除錯模式 set detach o...