2.6 Tracing Parent and Child Processes

When a process forks, it creates a child process that is effectively a copy of its parent process, but which has a different process ID. (Other differences are described on the fork(2) manual page.) The child process can either run independently of its parent process to perform some separate task, or it can execute a new program image that replaces the child's program image while retaining the same process ID.

The next D program uses proc probes to trace activity.d, reports fork() and exec() activity on a system.

Example 2.11 activity.d: Record fork() and exec() activity

#pragma D option quiet

/* activity.d -- Record fork() and exec() activity */

proc::do_fork:create
{
  /* Extract PID of child process from the psinfo_t pointed to by args[0] */
  childpid = args[0]->pr_pid;

  time[childpid] = timestamp;
  p_pid[childpid] = pid; /* Current process ID (parent PID of new child) */
  p_name[childpid] = execname; /* Parent command name */
  p_exec[childpid] = ""; /* Child has not yet been exec'ed */ 
}

proc::do_execve_common:exec
/p_pid[pid] != 0/
{
  p_exec[pid] = args[0]; /* Child process path name */
}

proc::do_exit:exit
/p_pid[pid] != 0 &&  p_exec[pid] != ""/ 
{
  printf("%s (%d) executed %s (%d) for %d microseconds\n",
    p_name[pid], p_pid[pid], p_exec[pid], pid, (timestamp - time[pid])/1000);
}

proc::do_exit:exit
/p_pid[pid] != 0 &&  p_exec[pid] == ""/
{
  printf("%s (%d) forked itself (as %d) for %d microseconds\n",
    p_name[pid], p_pid[pid], pid, (timestamp - time[pid])/1000);
}  


The statement #pragma D option quiet has the same effect as specifying the -q option on the command line.

The process ID of the child process (childpid) following a fork() is determined by examining the pr_pid member of the psinfo_t data structure pointed to by the args[0] probe argument. For more information about the arguments to proc probes, see proc Provider in the Oracle Linux Dynamic Tracing Guide.

The program uses the value of the child process ID to initialize globally unique associative array entries such as p_pid[childpid].

Note

An associative array is similar to a normal array in that it associates keys with values, but the keys can be of any type; they need not be integers.

When you run the program, you see output similar to the following, as you run different programs.

# dtrace -s activity.d 
bash (3572) executed /bin/ls (4323) for 6422 microseconds
bash (3572) executed /usr/bin/w (4324) for 128960 microseconds
firefox (4325) executed /bin/basename (4326) for 8548 microseconds
firefox (4325) executed /bin/uname (4327) for 1999 microseconds
mozilla-plugin- (4328) executed /bin/uname (4329) for 2151 microseconds
mozilla-plugin- (4328) executed /usr/lib64/nspluginwrapper/plugin-config (4330) 
        for 8182 microseconds
firefox (4325) executed /usr/lib64//xulrunner-1.9.2/mozilla-xremote-client (4331) 
        for 40067 microseconds
firefox (4333) forked itself (as 4334) for 200 microseconds
firefox (4333) executed /bin/sed (4335) for 1070 microseconds
firefox (4336) forked itself (as 4337) for 229 microseconds
firefox (4336) executed /bin/sed (4338) for 1161 microseconds
...