12.6.4 Predicates

Predicates are logic statements that select whether DTrace invokes the actions that are associated with a probe. For example, the predicates in the following program sc1000.d examine the value of the variable i. This program also demonstrates how to include C-style comments.

#pragma D option quiet

BEGIN
{
  /* Initialize i */
  i = 1000; 
}

syscall:::entry
/i > 0/
{
  /* Decrement i */
  i--; 
}

syscall:::entry
/(i % 100) == 0/
{
  /* Print i after every 100 system calls */
  printf("i = %d\n",i); 
}

syscall:::entry
/i == 0/
{
  printf("i = 0; 1000 system calls invoked\n");
  exit(0);  /* Exit with a value of 0 */
}

The program initializes i with a value of 1000, decrements its value by 1 whenever a process invokes a system call, prints its value after every 100 system calls, and exits when the value of 1 reaches 0. Running the program in quite mode produces output similar to the following:

# dtrace -s sc1000.d 
i = 900
i = 700
i = 800
i = 600
i = 500
i = 400
i = 300
i = 200
i = 100
i = 0
i = 0; 1000 system calls invoked

Note that the order of the countdown sequence is not as expected. The output for i=800 appears after the output for i=700. If you turn off quiet mode, it becomes apparent that the reason is that dtrace is collecting information from probes that can be triggered on all the CPU cores. You cannot expect runtime output from DTrace to be sequential in a multithreaded environment.

# dtrace -s sc1000.d 
dtrace: script 'sc1000.d' matched 889 probes
CPU     ID                FUNCTION:NAME
  0    457           clock_gettime:entry i = 900

  0    413                   futex:entry i = 700

  1     41                   lseek:entry i = 800

  1     25                    read:entry i = 600

  1     25                    read:entry i = 500

  1     25                    read:entry i = 400

  1     71                  select:entry i = 300

  1     71                  select:entry i = 200

  1     25                    read:entry i = 100

  1     25                    read:entry i = 0

  1     25                    read:entry i = 0; 1000 system calls invoked

The next example is an executable DTrace script that displays the file descriptor, output string, and string length specified to the write() system call whenever the date command is run on the system.

#!/usr/sbin/dtrace -s
#pragma D option quiet

syscall::write:entry
/execname == "date"/
{
  printf("%s(%d, %s, %4d)\n", probefunc, arg0, copyinstr(arg1), arg2);
} 

If you run the script from one window, while typing the date command in another, you see output such as the following in the first window:

write(1, Wed Aug 15 10:42:34 BST 2012
,   29)