Bug 10013

Summary: Support ENABLED sdt probe macro
Product: systemtap Reporter: Mark Wielaard <mjw>
Component: runtimeAssignee: Stan Cox <scox>
Status: RESOLVED FIXED    
Severity: normal CC: srikar
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Bug Depends on: 10010    
Bug Blocks: 10907    

Description Mark Wielaard 2009-03-30 09:37:06 UTC
Currently there is no way for a user program that uses sdt.h for stap static
dynamic probes to know whether or not a probe has been enabled at runtime. This
might be beneficial when setting up probe arguments is expensive. This is an
issue for some interpreters that have to translate function names, classes or
methods to (pointers to) strings for example. They don't want to do that extra
argument setup unless the probe is enabled at that time. TCL for example uses a
facility like that. Java hotspot currently requires being started with an extra
flag that always translates all probe arguments when enabled. This causes a
performance hit and makes those probes only available in this "special mode"
which kind of defeats the purpose of "zero-impact, always on tracing".

This would also help with dtrace emulation for sdt. Currently our dtrace python
wrapper script just outputs "#define %s_ENABLED() 1" for every dtrace emulated
probe.

The ENABLED probe macro should return 1 when the associated probe is enabled
(the uprobe/mark set in the executable/library) and 0 otherwise.
Comment 1 Frank Ch. Eigler 2009-03-30 15:37:38 UTC
One way to implement this could be to add a word-sized counter to the
.probes section that describes the probe point.  Translator-generated
code could attempt to atomically increment/decrement that when the
corresponding uprobe is placed/removed.  The ENABLED() macro would read that
value.

One way to make this somewhat less flaky/racy is to have all the counters
be set/cleared on a object-file-wide basis, when task-finder tells us it has
been loaded -- so before the user-space code starts to run.
Comment 2 Mark Wielaard 2009-04-05 19:17:30 UTC
Maybe we can teach uprobes to replace with a specific move/assignment
instruction instead of a trap instruction. Then you could define ENABLE_PROBE()
with something like:

#define ENABLED_PROBE() ({char e = 0; asm ("mov $0x0, %0" :"=r"(e):"0"(e)); e;})

(of course with the magic macro label .probe section stuff to know the actual
address of the mov instruction)

Then instead of with a normal STAP_PROBE replacing a "nop" with "int3", you
would replace the "mov $0x0, %somereg" with "mov $0x1, %somereg".
Comment 3 Frank Ch. Eigler 2009-04-05 21:56:42 UTC
> Maybe we can teach uprobes to replace with a specific move/assignment
> instruction instead of a trap instruction.

This optimization is the same as in the "move immediate" kernel markers.
However, it is not a *substitute* for a trap.  It is only a substitute
for a condition evaluation.

> Then instead of with a normal STAP_PROBE replacing a "nop" with "int3", you
> would replace the "mov $0x0, %somereg" with "mov $0x1, %somereg".

You still need some way to enter the kernel.
Comment 4 Mark Wielaard 2009-04-05 22:22:40 UTC
(In reply to comment #3)
> This optimization is the same as in the "move immediate" kernel markers.
> However, it is not a *substitute* for a trap.  It is only a substitute
> for a condition evaluation.
> [...]
> You still need some way to enter the kernel.

It isn't meant as substitute of the trap. That will still be the STAP_PROBE itself.

So the idea is that when enabling a probe, you first enable the PROBE itself,
replacing the nop with a trap, then, if there is also an associated ENABLED
conditional, you replace the move to enable the code path leading to the probe.
So user code would be written as:

if (STAP_PROBE_ENABLED(myapp, mymark))
 {
   do_expensive_argument_setup();
   STAP_PROBE(myapp, mymark, args);
 }
Comment 5 Stan Cox 2009-12-16 20:29:10 UTC
commit: 63b4fd14
Adds process("process").library("library").mark("mark")
And uses it, via the task manager, to implement enabled.