2.6.1 Example: Using proc Probes to Report Activity on a System (activity.d)

The D program activity.d in the following example uses proc probes to report fork() and exec() activity on a system.

#pragma D option quiet

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

  /* 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 */ 

/p_pid[pid] != 0/
  p_exec[pid] = args[0]; /* Child process path name */

/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);

/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);

In the example, 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 that is 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].


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 should see output similar to the following as you use the ssh command to access the same system from another terminal window. You might want to try running different programs from this new terminal window to generate additional output:

# dtrace -s activity.d 
sshd (3966) forked itself (as 3967) for 3667020 microseconds
bash (3971) forked itself (as 3972) for 1718 microseconds
bash (3973) executed /usr/bin/hostname (3974) for 1169 microseconds
grepconf.sh (3975) forked itself (as 3976) for 1333 microseconds
bash (3977) forked itself (as 3978) for 967 microseconds
bash (3977) executed /usr/bin/tput (3979) for 1355 microseconds
bash (3980) executed /usr/bin/dircolors (3981) for 1212 microseconds
sshd (3966) executed /usr/sbin/unix_chkpwd (3968) for 31444 microseconds
sshd (3966) executed /usr/sbin/unix_chkpwd (3969) for 1653 microseconds
bash (3970) forked itself (as 3971) for 2411 microseconds
bash (3970) forked itself (as 3973) for 1830 microseconds
bash (3970) executed /usr/libexec/grepconf.sh (3975) for 3696 microseconds
bash (3970) forked itself (as 3977) for 3273 microseconds
bash (3970) forked itself (as 3980) for 1928 microseconds
bash (3970) executed /usr/bin/grep (3982) for 1570 microseconds