3.4 Tracing the Flow of Execution

The next D program, flow.d, traces the flow of execution through func.php.

Example 3.3 flow.d: Trace the flow of execution in func.php

/* flow.d -- Trace the flow of execution in func.php */

self int indent;

php$target:::function-entry
/copyinstr(arg0) == "initialize"/
{
  self->follow = 1;
  self->indent += 2;
}

php$target:::function-entry
/self->follow/
{
  printf("%*s ", self->indent, "->");
  printf("%s() entry\n",copyinstr(arg0));
  self->indent += 2;
}

php$target:::function-return
/self->follow/
{
  self->indent -= 2;
  printf("%*s ", self->indent, "<-");
  printf("%s() return\n",copyinstr(arg0));
}

php$target:::function-return
/copyinstr(arg0) == "initialize"/
{
  self->follow = 0;
}

The program uses the PHP function-entry and function-return probes to trace the execution.

The probe provider is specified as php$target. As $target evaluates to the process ID of the program that is being traced, we start the PHP program by specifying it as the argument to the -c option to dtrace:

# dtrace -c 'php ./func.php' -q -s ./flow.d
-> initialize() entry
  -> tails() entry
    -> heads() entry
      -> heads() entry
      <- heads() return
    <- heads() return
  <- tails() return
<- initialize() return
-> initialize() entry
  -> heads() entry
    -> heads() entry
      -> tails() entry
        -> heads() entry
          -> tails() entry
          <- tails() return
        <- heads() return
      <- tails() return
    <- heads() return
  <- heads() return
<- initialize() return
-> initialize() entry
  -> heads() entry
  <- heads() return
<- initialize() return
^C