Since you are interested in each function that was entered and exited, a line should be printed for each, containing the function name. In order to make that list easy to read, systemtap should indent the lines so that functions called by other traced functions are nested deeper. To tell each single process apart from any others that may be running concurrently, systemtap should also print the process ID in the line.
Systemtap provides a variety of such contextual data, ready for
formatting. They usually appear as function calls within the handler,
like you already saw in Figure 1. See the
stapfuncs man page for those functions and more defined in the
tapset library, but here's a sampling:
tid() |
The id of the current thread. |
pid() |
The process (task group) id of the current thread. |
uid() |
The id of the current user. |
execname() |
The name of the current process. |
cpu() |
The current cpu number. |
gettimeofday_s() |
Number of seconds since epoch. |
get_cycles() |
Snapshot of hardware cycle counter. |
pp() |
A string describing the probe point being currently handled. |
probefunc() |
If known, the name of the function in which this probe was placed. |
The values returned may be strings or numbers. The print()
built-in function accepts either as its sole argument. Or, you can
use the C-style printf() built-in, whose formatting argument
may include %s for a string, %d for a number.
printf and other functions take comma-separated arguments.
Don't forget a "\n" at the end.
A particularly handy function in the tapset library is
thread_indent. Given an indentation delta parameter, it stores
internally an indentation counter for each thread (tid()), and
returns a string with some generic trace data plus an appropriate
number of indentation spaces. That generic data includes a timestamp
(number of microseconds since the most recent initial indentation), a
process name and the thread id itself. It therefore gives an idea not
only about what functions were called, but who called them, and how
long they took. Figure 3 shows the finished
script. It lacks a call to the exit() function, so you need to
interrupt it with ^C when you want the tracing to stop.