Processes That Use fork()

The debugger has the following predefined variables that you can set for debugging a program that forks:

When a fork occurs, the debugger sets the debugger variables $childprocess and $parentprocess to the child and parent process IDs, respectively.

In the following example, the debugger notifies you that the child process has stopped. The parent process continues to run.

 

(idb) set $catchforks = 1

(idb) run

Process 29027 forked.  The child process is 29023.

Process 29023 stopped on fork.

stopped at [int main(void):6 0x120001178]

      6  int pid = fork();

fork.c: I am the parent.

Process has exited with status 0

(idb) show process

>localhost:29028 (/home/user/examples/fork) loaded.

 localhost:29023 (/home/user/examples/fork) paused.

 

In the preceding example, note the following:

Continuing the previous example, the following shows how to switch the debugger to the child process. Listing the source code shows the source for the child process.

 

(idb) process $childprocess

(idb) show process

 localhost:29028 (/home/user/examples/fork) loaded.

>localhost:29023 (/home/user/examples/fork) paused.

(idb) list

      7

      8   if (pid == 0)

      9    {

     10      printf("fork.c: I am the child.\n");

     11    }

     12   else

     13    {

     14      printf("fork.c: I am the parent.\n");

     15    }

     16 }

 

In the preceding example, note the following:

Note:

If you catch the child but not the parent, and the parent code tries to execute a wait on the child, the target will get stuck if you don't let the child run to completion. This happens because the parent will be running but making no progress, and the child is stopped by the debugger. For example:

(idb) set $catchforks = 1

(idb) set $stopparentonfork = 0

(idb) list

     10     int new_pid = 0;

     11

     12     if (pid == 0) {

     13         printf( "fork.c: I am the child.\n" );

     14 fflush( stdout );

     15

     16     } else {

     17         printf( "fork.c: I am the parent, about to wait.\n" );

     18 fflush( stdout );

     19

     20 new_pid = wait( &status );

     21

     22         printf( "fork.c: I am the parent, and my wait is finished\n" );

     23

     24         if (new_pid != pid )

     25             printf( "\tthere was some error\n" );

     26         else {

     27     if (WIFEXITED(status))

     28                 printf( "\tthe child terminated normally\n" );

     29

     30             else if (WIFSIGNALED(status))

(idb) sh cat ./x.c_fork_hang.txt

  If we 'cont' now, the process will fork; the child will be

  caught and the parent will run to the 'wait' call and wait

  for the child to terminate.

  At that time, the child will be under debugger control,

  but the current process will be the parent, which will be

  running but making no progress.  Only a Ctrl/C will allow

  further progress.

  The example program has set up another process to simulate

  a Ctrl/C by the user.  It will send SIGINT to the parent.

(idb) cont

Process 580893 forked.  The child process is 580851.

Process 580851 stopped on fork.

stopped at [void test(void):9 0x120001318]

      9     int pid = fork();

fork.c: I am the parent, about to wait.

:

User is waiting here

:

:

Sending SIGINT to parent process

:

Thread received signal INT

stopped at [<opaque> __wait4(...) 0x3ff800d0918]

Information:  An <opaque> type was presented during execution of the previous command.  For complete type information on this symbol, recompilation of the program will be necessary.  Consult the compiler man pages for details on producing full symbol table information using the '-g' (and '-gall' for cxx) flags.

(idb) where

>0  0x3ff800d0918 in __wait4(...) in /usr/shlib/libc.so

#1  0x3ff800d668c in __wait(...) in /usr/shlib/libc.so

#2  0x120001398 in test() "c_fork_hang.c":20

#3  0x120001528 in main() "c_fork_hang.c":71

#4  0x1200012a8 in __start(...) in /home/user/examples/c_fork_hang

(idb) show process

>localhost:580893 (/home/user/examples/c_fork_hang) paused.

   \_localhost:580851 (/home/user/examples/c_fork_hang) paused.