node-dtrace-provider
node-dtrace-provider copied to clipboard
Function name and probe name always seem to be the same
I'm just starting to use DTrace with node, but have noticed that the function name and probe name seem to be the same. For example, when using:
var dtp = d.createDTraceProvider('myprovider', 'mymodule'),
myProbe = dtp.addProbe('myprobe', 'char *');
dtrace -l will return:
ID PROVIDER MODULE FUNCTION NAME
<id> myprovider<pid> mymodule myprobe myprobe
where 'myprobe' is listed as both the function name and probe name. However, for other probes, I see separate function and probe names:
ID PROVIDER MODULE FUNCTION NAME
<id> syscall write entry
<id> syscall write return
<id> syscall open entry
<id> syscall open return
Digging into DTraceProvider::AddProbe()
shows the call to usdt_create_probe passing the name as both the function name and probe name:
probe->probedef = usdt_create_probe(*name, *name, probe->argc, types);
Is this intentional?
The "module" and "function" that DTrace knows about were historically the native module (i.e., kernel module, shared library, or "a.out") and native function name where the probe itself is defined. See http://dtrace.org/guide/chapter.html#chp-intro-3
This makes sense for the native environments DTrace was initially created for, and I'm not sure whether these fields were intended to be generalized to mean something more useful for dynamic environments. I can see arguments both ways, so I'd defer to @bcantrill on this.
CC'ing @tjfontaine, who's also wondered about this.
Thanks for the response, Dave.
This makes sense for the native environments DTrace was initially created for, and I'm not sure whether these fields were intended to be generalized to mean something more useful for dynamic environments.
I would argue that having dtrace-provider at all shows intention to make DTrace more useful for dynamic environments. We can already specify provider, module, and probe names to be something meaningful for our application, being able to specify the function name simply adds to that utility.
An example use case is: I want to profile high-level entry points to a module to see how it is being used. With the pid provider on native code, I could set up a probe on app1234:mymodule::entry, and aggregate on call stack (to see usage), or start a timer. However, if I want to trace what is calling one of my functions that is producing an error, I would need to set up a probe on app1234:mymodule:myfunction:entry.
I can solve the first case by having a single pair of entry and exit probes for my module:
dtp.addProbe('entry', ...);
and calling it from each entry point. I can solve the second case by creating a separate probe for each function entry and exit in my module:
dtp.addProbe('function1-entry', ...);
dtp.addProbe('function2-entry', ...);
dtp.addProbe('function3-entry', ...);
and setting my DTrace script to fire on just the one probe. I suppose I could work around this by creating both sets of probes, but this isn't the nicest solution.