12.6.1 User Function Boundary Tracing

The simplest mode of operation for the pid provider is to provide function boundary tracing in user space. The following example program traces all of the function entries and returns that are made from a single function. The $1 macro variable, the first operand on the command line, is the process ID for the process to trace. The $2 macro variable, the second operand on the command line, is the name of the function from which to trace all function calls. Type the following source code and save it in a file named userfunc.d:

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

pid$1::$2:entry
{
  self->trace = 1;
}

pid$1:::entry,
pid$1:::return
/self->trace/
{
}

pid$1::$2:return
/self->trace/
{
  self->trace = 0;
}

Type the previous example script and save it in a file named userfunc.d, then use the chmod command to make the file executable. This script produces output with more details on the principal buffer:

# ./userfunc.d 123 execute
dtrace: script ’./userfunc.d’ matched 11594 probes
  0  -> execute
  0    -> execute
  0      -> Dfix
  0      <- Dfix
  0      -> s_strsave
  0        -> malloc
  0        <- malloc
  0      <- s_strsave
  0      -> set
  0        -> malloc
  0        <- malloc
  0      <- set
  0      -> set1
  0        -> tglob
  0        <- tglob
  0      <- set1
  0      -> setq
  0        -> s_strcmp
  0        <- s_strcmp
...

The pid provider can only be used on processes that are already running. You can use the $target macro variable (see Chapter 9, Scripting) and the dtrace command with the -c and -p options to create and grab processes of interest and instrument them by using DTrace.

For example, you can use the following D script to determine the distribution of function calls that are made to libc by a particular subject process. Type the following source code and save it in a file named libc.d:

pid$target:libc.so::entry
{
  @[probefunc] = count();
}

To determine the distribution of such calls that are made by the date command, save the script in a file named libc.d and run the following command:

# dtrace -s libc.d -c date
dtrace: script ’libc.d’ matched 2476 probes
Fri Jul 30 14:08:54 PDT 2004
dtrace: pid 109196 has exited

  pthread_rwlock_unlock                         1
  _fflush_u                                     1
  rwlock_lock                                   1
  rw_write_held                                 1
  strftime                                      1
  _close                                        1
  _read                                         1
  __open                                        1
  _open                                         1
  strstr                                        1
  load_zoneinfo                                 1
...
  _ti_bind_guard                               47
  _ti_bind_clear                               94