GDB調試fork+exec創建的子進程的方法

多進程是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創建的多個子進程的調試方法,一旦有進展將會及時和大家分享。

發佈了33 篇原創文章 · 獲贊 6 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章