1. 程式人生 > >GDB除錯fork+exec建立的子程序的方法

GDB除錯fork+exec建立的子程序的方法

多程序是Linux程式設計中一個很重要的內容,典型的例子就是守護程序(daemon)。有關守護程序的定義和程式設計規範,請參考:

最常見的多程序的形式如下:

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