dtruss on Mac OS X


I appreciate the flexibility of Dtrace. But, at least on Mac OS X, the dtruss command is inferior to the classic truss command of UNIX System V that I’m used to using. Primarily because

a) You can’t run dtruss as yourself against a process you own. You have to run dtruss as the root user.

b) Using dtruss has a very noticeable impact on every other process even when tracing a specific PID (process ID). When I say “noticeable” I mean that UI events such as changing the window focus is noticeably affected. Which is unacceptable unless you are desperate to see what is happening within a specific process.

Even more annoying is that the standard dtruss command does not have any option for including wall-clock timestamps in its output. This makes correlating the dtruss output with output from the program being traced or other sources more challenging than it should be. Other people agree with me. Such as MadLab from which I based my own improvement to the Mac OS X dtruss enhancement.

A major problem with the solution by MadLab is that it relies on the brain-dead “printf(%Y)” specifier which has a resolution of one second and a format that isn’t easily handled by other programs; thus violating one of the primary tenets of UNIX programs. My solution is to also print the walltimestamp value using the “printf(%u)” specifier.

To make this useful enhancement simply copy /usr/bin/dtruss to a private directory in your $PATH. Then every place there is a OPT_printid ? printf precede that line with these two lines:

OPT_wallts   ? printf("%u  ", walltimestamp) : 1;
OPT_wallts   ? printf("%Y  ", walltimestamp) : 1;

The other changes to add the OPT_wallts option are fairly obvious but I include the patch below. This omits all the places where the aforementioned printf statements would be added.

`

3a4,6
> # krader: This is the Mac OS X standard /usr/bin/dtruss modified to include a
> # -w option to display the wall-clock timestamp with each syscall.
> #
74a78
> opt_wallts=0;
77c81
< while getopts ab:cdefhln:op:st:L name
---
> while getopts ab:cdefhln:op:st:Lw name
85c89
< opt_printid=1; opt_cpu=1 ;;
---
>       opt_printid=1; opt_cpu=1; opt_wallts=1 ;;
93a98
>   w)  opt_wallts=1 ;;
164a170
>  inline int OPT_wallts    = '$opt_wallts';
172a179
>   OPT_wallts   ? printf("%-21s  ", "TIMESTAMP") : 1;

`