DTrace: figuring out what you have access to at tracepoints
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 *, iscsi_cmd_state_str(icmdp->cmd_state), 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.
|
|