多進程是Linux編程中一個很重要的內容,典型的例子就是守護進程(daemon)。有關守護進程的定義和編程規範,請參考:
http://blog.csdn.net/tuzhutuzhu/article/details/19092211
最常見的多進程的形式如下:
pid = fork();
if (pid < 0) { // fork failed
printf("fork error\n");
exit(1);
} else if (pid > 0) { // parent process
// command
} else { // child process
// command
}
對於這種類型的多進程程序的調試,在gdb中使用選項follow-fork-mode即可。
使用:set follow-fork-mode child,即可追蹤子進程。而set follow-fork-mode parent可調試父進程。
還有一種多進程程序的形式爲:
pid = fork();
if (pid < 0) { // fork failed
printf("fork error\n");
exit(1);
} else if (pid > 0) { // parent process
// command
} else { // child process
execv("a.out", NULL);
}
這種程序的調試則要困難一些,下面我們通過一個實際的例子來看一下它的調試方法。
當前有兩個代碼test.c和child.c,其中test.c中的子進程通過execv調用child.c。
test.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int ret = 0;
ret = fork();
if (ret == 0) {
execv("a.out", NULL); //a.out是child.c編譯成的可執行文件
}
return 0;
}
child.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
my_print();
return 0;
}
int my_print()
{
printf("hello world\n");
return 0;
}
使用gdb調試的詳細過程如下所示:
上面的例子中,最重要的操作時catch exec這個事件。捕獲到exec這個事件之後再往子進程的程序中打一個斷點,然後執行continue操作。可以看到,此時程序就會進入到exec調用的子進程中了。
網上介紹gdb調試fork+exec創建的子進程的方法有不少,實際使用之後覺得,還是這種方法操作起來較爲簡潔明瞭。大家如果有什麼更好的方法,請一定告訴我。
後記:
本文主要介紹的是使用gdb調試fork+exec創建的子進程的方法。雖然方法是知道了,但是在實際的工作中,這種方法的實用性並不是十分的高。因爲上述方法有很大的侷限性:這種方法只能用在父進程中僅有一個exec的程序中。
當程序中存在多個fork+exec,使用上述的方法只能進入到第一個子進程中!!因此,想要調試其他的子進程就不行了。然而,對於任意一個子進程都可以自由的進行調試,纔是我的真正目標。我也會繼續調查gdb對於fork+exec創建的多個子進程的調試方法,一旦有進展將會及時和大家分享。