[測試程序]
咱們先看看咱們的測試程序:
/* in eg1.c */
int wib(int no1, int no2)
{
int result, diff;
diff = no1 - no2;
result = no1 / diff;
return result;
}
int main()
{
pid_t pid;
pid = fork();
if (pid <0) {
printf("fork err\n");
exit(-1);
} else if (pid == 0) {
/* in child process */
sleep(60); ------------------ (!)
int value = 10;
int div = 6;
int total = 0;
int i = 0;
int result = 0;
for (i = 0; i < 10; i++) {
result = wib(value, div);
total += result;
div++;
value--;
}
printf("%d wibed by %d equals %d\n", value, div, total);
exit(0);
} else {
/* in parent process */
sleep(4);
wait(-1);
exit(0);
}
}
該測試程序中子進程運行過程當中會在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 xxxxx --- xxxxx爲利用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
至此,咱們調試完畢。shell