Debugging a child process

Updated: April 19, 2023

By default, when a process creates another process, GDB doesn't follow the execution of the child process. You must attach another instance of the debugger to this new process; this action lets you debug the parent and child concurrently.

Note: If you need to debug only the child and not the parent, you can instruct the gdb utility to instead follow the child's code path.
The best strategy for debugging a child process is to make the child send a SIGSTOP signal to itself right after the fork() statement that creates it. This stops the process so you can attach the debugger and manually resume execution or step through the child's code.
To debug a child process concurrently with its parent:
  1. Set a breakpoint in the parent code path right after the fork() statement.
  2. In the launch bar, select the appropriate project and launch target, and the Debug launch mode.
  3. Click the Debug button (Icon: Debug button).
    The IDE switches to the Debug perspective, which displays the source code being traced and the current variables and breakpoints. If necessary, the IDE builds the application and uploads the binary to the target. Then, it runs the binary and GDB, which it attaches to the binary.
  4. If GDB stops on startup, press F8 or click the Resume button at the top of the Debug view to continue execution.
    The program runs until the breakpoint just after the fork() call in the parent code path. The child process will now be running and if you added a line to send the SIGSTOP signal, it will be stopped at that line.
  5. Learn the ID of the child process.

    In the Variables view, you can examine the variable that stores the fork() result. Because GDB is following the parent code path, this variable shows the PID of the new child.

    You can also switch to the QNX System Information perspective and in the System Summary view, find the processes with same name as the binary you're running. The child process will most likely have a PID that's a slightly higher number than that of the parent.

  6. In the Launch Mode dropdown, select Attach.
  7. Click the Attach button (Icon: Attach button).
    The IDE opens the Select Process window, which lists the processes with the same name as the binary specified in the launch configuration settings.
  8. Click the entry for the child process you want to debug, then click OK.
    The IDE runs another GDB instance, attaches it to the child process, and displays an entry for this process in the Debug view. If the child's main thread has been stopped by the SIGSTOP signal, the thread label contains the word STOPPED. You can start debugging the child code by pressing F7 or clicking the Step Return button at the top of the view, once to step out of the SignalKill() call and then again to step out of kill() and back into the main thread.

You can now debug the child and parent processes concurrently, by alternating between the different sessions in the Debug view. When you click a session entry, you access the GDB instance attached to the corresponding process and any debugging actions you then perform (e.g., resuming execution, stepping through code) are applied to that process. This design lets you attach GDB instances to several child processes and debug all of them concurrently.

For information on the debugging controls, see Debug perspective controls.

Following execution into a child process

Updated: April 19, 2023

When a program executes a fork() statement, GDB by default follows the parent code path. To make GDB follow the child code path instead, you must preset the right mode in the gdb utility.

In the Debug tab of the launch configuration, you can name a command file that GDB executes whenever it starts up. In this file, you can preset the child-following mode using this command:

set follow-fork-mode child

This strategy is handy when you always want to follow the code path of the child instead of the parent. If you want to debug into the child only occasionally, you can manually set this mode before the child process gets created. To do so, you must first verify that GDB is configured to stop on startup, so you have time to issue the necessary gdb command.

To manually follow execution into the child:
  1. Select the project, target, and Debug launch mode in the launch bar, then click the Debug button.
    The IDE switches to the Debug perspective, starts GDB, and attaches it to the application process. GDB stops the application on startup, at the first line in main() (if you use default settings).
  2. Click the Console view to interact with the gdb utility.
    In this view, the IDE should show the gdb output, as indicated by the utility's path given in the view header. If you don't see the gdb output initially, click the Display Selected Console button (Icon: Display Selected Console button) in the upper right area and select the gdb binary entry.
  3. Enter the command set follow-fork-mode child.
    You can confirm this setting by typing show follow-fork-mode; gdb then displays this message:
    Debugger response to a program call of fork or vfork is "child".
  4. Press F8 or click the Resume button in the Debug view to continue execution.

GDB lets the application run and create the child process. When this happens, GDB follows execution into the child when the program executes the fork() call.

For information on the debugging controls, see Debug perspective controls.