DTrace: figuring out what you have access to at tracepoints

November 7, 2012

I've said before that OpenSolaris (or Illumos) source code is an essential component for serious use of DTrace, because it's what you need in practice to figure out how to get useful information out of the kernel. But sometimes you don't want to go spelunking through OpenSolaris code to find structure definitions and all of that, and you'd like a more convenient way. As it happens, there sort of is.

The first step is to find out what arguments are available at a particular DTrace tracepoint. DTrace has this information available (because it uses it to complain if you get things wrong), but it doesn't make this readily accessible. For function tracepoints, you can use an undocumented feature of 'dtrace -v' (at least in Solaris 10 update 8); it will print argument details as well as the uninteresting stability level stuff. For example, 'dtrace -vln fbt::zio_create:entry' reports (for me) that the second argument (args[1]) is a spa_t *.

That's nice, but what's in that spa_t that we have a pointer to? For that, we turn to mdb -k and its '::print -t' command, because the debugger (like DTrace itself) knows all about the structures in your kernel. For example:

# mdb -k
Loading modules: [....]
> ::print -t spa_t
    char [256] spa_name 
    avl_node_t spa_avl {
        struct avl_node *[2] avl_child 
        uintptr_t avl_pcb 
    nvlist_t *spa_config 
[.. huge output elided ..]

What all of this will not tell you is what these structures and fields mean and what the various functions use them for. For that, you need the source code. However, using mdb to dump structures has two advantages. First, it's generally faster than trying to find and read the right header file in the depths of the source code tree. Second, it's guaranteed to be accurate for your kernel (which is not true for the OpenSolaris source code). The second bit makes mdb the thing to turn to on the occasions when DTrace is telling you that some structure member is missing when you can clearly see it there in the source code.

Unfortunately 'dtrace -v' will not tell you information about the arguments for non-fbt tracepoints (at least in my version and as far as I can tell). For that you need to read the source code itself. What you want to look at is the various DTRACE macros; for example, in iscsi_cmd_state_machine we have:

DTRACE_PROBE3(event, iscsi_cmd_t *, icmdp, char *,
    char *, iscsi_cmd_event_str(event));

This corresponds to sdt::iscsi_cmd_state_machine:event. This DTrace tracepoint has three arguments, an iscsi_cmd_t *, a char *, and then another char *, and you can also see what function arguments they correspond to. Again, for what they mean you need to read the surrounding code.

(This particular sdt tracepoint is almost exactly equivalent to fbt::iscsi_cmd_state_machine:entry, but there are more useful sdt tracepoints. Sometimes they expose execution paths and information that are hard or all but impossible to get with function tracepoints alone.)

PS: that DTrace refuses to tell you information that it knows makes me very annoyed. There is no excuse for hiding this stuff. Doing so is yet another sign that despite propaganda to the contrary, DTrace is not actually designed for anyone except the OS vendor. Make no mistake, it's a great tool if you're the OS vendor or can fake it, but if you're not, forget it.

Written on 07 November 2012.
« Why I want to do full end-to-end performance tests
Devops, the return of system programmers? »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Nov 7 01:27:53 2012
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.