[ltt-dev] LTTng-UST vs SystemTap userspace tracing benchmarks

Mark Wielaard mjw at redhat.com
Wed Feb 16 05:56:18 EST 2011


On Tue, 2011-02-15 at 17:00 +0000, Stefan Hajnoczi wrote:
> On Tue, Feb 15, 2011 at 4:26 PM, Frank Ch. Eigler <fche at redhat.com> wrote:
> > (One may imagine a future version of systemtap where scripts that
> > happen to independently probe single processes are executed with a
> > pure userspace backend, but this is not in our immediate roadmap.)
> 
> What is the fundamental mechanism that UST and SystemTap use for tracing?
> 
> e.g. Here's a guess:
> UST: a conditional function call within the same process
> SystemTap: a software interrupt on x86
> 
> I don't know the implementations details but would be interested in
> understanding this.

I don't know the precise implementation details for ltt. But for
SystemTap you could divide the "tracing" process into a couple of steps:

1) The probe marking. The way you embed where you can place probes and
   how to get at arguments/context of the probe. For userspace probes
   SystemTap mainly relies on two mechanisms:

 - dwarf debuginfo. This is the same mechanism debuggers use. It is a
   very low level description of how the source program maps to the
   binary. Through it you can determine locations for probes based on
   source lines, function names, etc. and get a description of how to
   get at local variables and arguments. Advantage is that it is already
   there (when compiled -g), so you don't need to do anything special.
   Downside is that it is pretty low level, so you do need to know a bit
   about the program structure before you can "trace" effectively.
   Recent advancements in gcc made the dwarf debuginfo pretty reliable.

 - sdt markers. This is a mechanism also employed by dtrace (although
   the way the markers and arguments are embedded is slightly different,
   this is an implementation detail though). A program #include
   <sys/sdt.h> and places PROBE markers in their source code to indicate
   "high-level events" and relevant arguments for that event.
   The macros get translated to special code that places the name,
   address and where to find the arguments into a special elf note.
   Advantage is that as a "trace user" you get an overview of high level
   events that might be interested to introspect. Disadvantage is that
   the programmer needs to explicitly embed them in their program (but
   since dtrace and now gdb can also hook onto them they are getting
   used more and more).

2) The probe and context selection. In a systemtap stap script you
   list all places/events you want to place a probe on. These can be
   low level kernel events (tracepoints, based on kernel debuginfo,
   timers, perf events, etc) or user level events (based on the dwarf
   debuginfo or sdt markers placed in the program). Then for each (group
   of) probe events, you write a handler listing the context you are
   interested in (variables, arguments, etc.). These can then be used to
   filter and/or log the event (see under 5. The actual "trace").

4) Hooking onto the probe. Based on the stap script you provide the
   systemtap runtime decides which addresses to place probes on (or hook
   into event notifiers). It also extracts the location of each context
   variable and/or parameter used in the probe handler for that
   location. Currently for each user space address derived (which could
   be multiple if the probe point is inlined in various places) it uses
   uprobes to place a breakpoint instruction at that location and
   inserts a callback handler to the handler responsible for that probe
   event. All the nitty-gritty of placing the probes and handling the
   software interrupt is delegated to uprobes (it saves a full roundtrip
   user/kernel/user necessary with for example ptrace), which is being
   pushed into the upstream kernel so it can be used by others like perf
   and gdb in the future. But you could imagine hooking being done
   through other mechanisms, like in-process functional calls in the
   user process. If the code injection techniques of ltt are reusable
   that would be a very cool idea.

5) The actual "trace"/data gathering step. Depending on the stap
   handler you wrote for the probe the SystemTap runtime (called
   through the probe hook) will extract the context variables
   and/or parameters you are interested in. They are then used for
   filtering (based on the conditionals used in your handler) and
   then lets you either assign derived values to global (script)
   variables or statistical containers, or make you log the event
   and/or some of the context. Basically you write a log or printf
   statement in your handler when you want to "trace" it. Depending
   on how you invoked stap it is then placed in a file or some buffer
   through procfs, relayfs, debugfs or ring_buffers. Alternatively
   you can write an "end" handler that just spits out the data you
   accumulated and stored in the script variables and statistics
   (so as not to have to output anything at all during the probe
    event itself to save data output and processing time).

Hope that helps. And if someone could give a similar overview of ltt
then we could see how we can more easily mix and match these various
steps in the future. Since it seems the mechanisms used are nicely
complementary.

Cheers,

Mark





More information about the lttng-dev mailing list