gdb除錯多程式

uestczshen發表於2016-11-19
在大多數系統,gdb對使用fork建立的程式沒有進行特別的支援。當父程式使用fork建立子程式,gdb仍然只會除錯父程式,而子程式沒有得到控制和除錯。這個時候,如果你在子程式執行到的程式碼中設定了斷點,那麼當子程式執行到這個斷點的時候,會產生一個SIGTRAP的訊號,如果沒有對此訊號進行捕捉處理,就會按預設的處理方式處理——終止程式。

    當然,你可以使用時間延遲的方法,在子程式fork出來之後,使用Sleep函式等待一段時間再執行,在這段時間中你使用ps找到該程式,然後使用Attach方法把該程式附加到gdb中,從而達到可以除錯子程式的目的。

    在一部分系統中(我使用的是基於2.6核心的CentOS,支援follow-fork和detach-on-fork模式),比如HP-UX11.x之後的版本,Linux2.5.60之後的版本,可以使用以下的方法來達到方便的進行多程式除錯功能。

    預設情況下,父程式fork一個子程式,gdb只會繼續除錯父程式而不會管子程式的執行。

    如果你想跟蹤子程式進行除錯,可以使用set follow-fork-mode mode來設定fork跟隨模式。

    set follow-fork-mode 所帶的mode引數可以是以下的一種:

    parent

        gdb只跟蹤父程式,不跟蹤子程式,這是預設的模式。

    child

        gdb在子程式產生以後只跟蹤子程式,放棄對父程式的跟蹤。

    進入gdb以後,我們可以使用show follow-fork-mode來檢視目前的跟蹤模式。

    可以看到目前使用的模式是parent。

    然而,有的時候,我們想同時除錯父程式和子程式,以上的方法就不能滿足了。Linux提供了set detach-on-fork mode命令來供我們使用。其使用的mode可以是以下的一種:

    on

        只除錯父程式或子程式的其中一個(根據follow-fork-mode來決定),這是預設的模式。

    off

        父子程式都在gdb的控制之下,其中一個程式正常除錯(根據follow-fork-mode來決定)

    另一個程式會被設定為暫停狀態。

    同樣,show detach-on-fork顯示了目前是的detach-on-fork模式,如上圖。

    以上是除錯fork產生子程式的情況,但是如果子程式使用exec系統函式而裝載了新程式執行呢?——我們使用set follow-exec-mode mode提供的模式來跟蹤這個exec裝載的程式。mode可以是以下的一種:

    new 當發生exec的時候,如果這個選項是new,則新建一個inferior給執行起來的子程式,而父程式的inferior仍然保留,當前保留的inferior的程式狀態是沒有執行。

    same 當發生exec的時候,如果這個選項是same(預設值),因為父程式已經退出,所以自動在執行exec的inferior上控制子程式。

    我們可以使用apue裡面第8章的例子程式碼來做測試:

    

#include "apue.h"

intglob = 6;/* external variable in initialized data */

charbuf[] = "a write to stdout\n";

int

main(void)

{

intvar;/* automatic variable on the stack */

pid_tpid;

var = 88;

if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)

err_sys("write error");

printf("before fork\n");/* we don't flush stdout */

if ((pid = fork()) < 0) {

err_sys("fork error");

} else if (pid == 0) {/* child */

glob++;/* modify variables */

var++;

} else {

sleep(2);/* parent */

}

printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);

exit(0);

}   

相關文章