gdb调试fork多进程
在大多數系統,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);
} ? ?
總結
以上是生活随笔為你收集整理的gdb调试fork多进程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: apr_pool -- 内存池
- 下一篇: Zookeeper 安装和配置---学习