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 モードがデフォルトモードになります。