5.3.4. フォークされる実行
プログラマーが直面するバグの中でも、1 つのプログラム (親) がそれ自体の独立したコピー (フォーク) を作成するケースに関連するバグがとりわけ困難になります。そのフォークは子プロセスを作成し、その結果失敗してしまいます。親プロセスのデバッグは役に立つ場合とそうでない場合があります。バグに辿り着く唯一の方法は子プロセスのデバッグである場合がよくありますが、これは常に可能とは限りません。
set follow-fork-mode
機能は、この障害を克服するために使用され、プログラマーが親プロセスの代わりに子プロセスに従うことを可能にします。
set follow-fork-mode parent
- 元のプロセスがフォークの後にデバッグされます。子プロセスは問題なく実行されます。これはデフォルトです。
set follow-fork-mode child
- 新規プロセスがフォークの後にデバッグされます。親プロセスは問題なく実行されます。
show follow-fork-mode
- フォーク呼び出しに対する現在のデバッガー応答を表示します。
set detach-on-fork
コマンドを使用して、フォーク後に親プロセスと子プロセスの両方をデバッグするか、またはそれらの両方に対してデバッガー制御を保持します。
set detach-on-fork on
- 子プロセス (または
follow-fork-mode
の値によっては親プロセス) が切り離され、別個に実行できるようになります。これはデフォルトです。 set detach-on-fork off
- 両方のプロセスが GDB の制御下に保持されます。1 つのプロセス (
follow-fork-mode
の値に応じて子または親のどちらか) のデバッグが、他方が一時停止している間に通常どおり実行されます。 show detach-on-fork
detach-on-fork
モードがオンであるか、またはオフであるかどうかを表示します。
以下のプログラムを見てみましょう。
fork.c
#include <unistd.h> int main() { pid_t pid; const char *name; pid = fork(); if (pid == 0) { name = "I am the child"; } else { name = "I am the parent"; } return 0; }
このプログラムは、コマンド
gcc -g fork.c -o fork -lpthread
でコンパイルされ、GDB で検査された後に、以下を表示します。
gdb ./fork [...] (gdb) break main Breakpoint 1 at 0x4005dc: file fork.c, line 8. (gdb) run [...] Breakpoint 1, main () at fork.c:8 8 pid = fork(); (gdb) next Detaching after fork from child process 3840. 9 if (pid == 0) (gdb) next 15 name = "I am the parent"; (gdb) next 17 return 0; (gdb) print name $1 = 0x400717 "I am the parent"
GDB は親プロセスに従い、子プロセス (プロセス 3840) の実行継続を許可します。
以下は、
set follow-fork-mode child
を使用した同じテストです。
(gdb) set follow-fork-mode child (gdb) break main Breakpoint 1 at 0x4005dc: file fork.c, line 8. (gdb) run [...] Breakpoint 1, main () at fork.c:8 8 pid = fork(); (gdb) next [New process 3875] [Thread debugging using libthread_db enabled] [Switching to Thread 0x7ffff7fd5720 (LWP 3875)] 9 if (pid == 0) (gdb) next 11 name = "I am the child"; (gdb) next 17 return 0; (gdb) print name $2 = 0x400708 "I am the child" (gdb)
GDB は、ここで子プロセスに切り替えました。
この設定を適切な
.gdbinit
に追加すると、永続的な設定にすることができます。
たとえば、
set follow-fork-mode ask
が ~/.gdbinit
に追加されると、 ask モードがデフォルトモードになります。