[Mono-dev] [PATCH] Mono DTrace provider
Andreas Färber
andreas.faerber at web.de
Tue May 27 18:17:57 EDT 2008
Hi,
Am 27.05.2008 um 21:39 schrieb Miguel de Icaza:
>
>> i) A static probe has a performance impact even when the probe itself
>> is not enabled. It's small, somewhere in the order of five nop
>> instructions, I read for Solaris 10. On OSX the header file has one
>> function call (and there is no postprocessing step to change this).
>> Didn't do any benchmarks myself though.
>> If we later add further static probes on "hot" paths such as JIT
>> method compilation, I thought some people would not want to have that
>> feature enabled if they know they'd not use it. But you're right, if
>> anyone is so worried about performance they could of course
>> explicitly
>> use --disable-dtrace.
>
> Where do those probes go?
I'm not sure I understand the question.
A DTrace provider defines a set of potential user-land statically
defined tracing (USDT) probes, those are defined in the .d file my
patch puts into data/. They are defined in a C-like syntax and can
have up to nine arguments (numbers, pointers, UTF-8 strings iirc).
From this set of potential probes, a header file with C macros is
generated, in my patch in mono/utils/. We can use those macros
anywhere we like in our C functions. (In my patch, they only
incidentally correspond to begin and end of functions, they don't have
to. They could well be inside a loop, called with varying parameters.
I put them into mono/mini/mini.c and mono/metadata/boehm-gc.c for a
start.)
If we enable those probes at build time (by not having the macros be
empty), 'placeholders' get generated in the code, with the probes
disabled by default at runtime. The dynamic part about DTrace is that
only when a script is interested in a certain probe, those probe
points get enabled at runtime to actually do something.
Where we decide to put probes is up to us. A DTrace-aware operating
system offers the ability to trace function flow via 'pid' provider,
so we don't have to add probes to every function just to trace the
control flow; the real value is rather in providing the DTrace
environment with convenient event hooks that can be further processed
by the user in Sun's D scripting language. What the user actually does
with them is up to her, for example probe data could just be
printf'ed, or statistics could be aggregated and dumped at exit or
periodically.
The runtime probes and probe points that I have proposed as a start
were for begin and end of the runtime initialization, and for begin
and end of a garbage collection, for the Boehm GC only. The GC probes
might be extended to provide the generation as a parameter, for
instance.
Further probes should be added in all places where Mono's own --trace
mechanism operates, but I'm interested in feedback before I proceed.
That's because the side effect is, that for Solaris every object file
with a probe point needs to be postprocessed before linking, and this
needs to be done for all object files involved in a certain
executable. But it can neither be done incrementally, e.g. per .a
file, nor repeatedly on the same object file for multiple executables
(therefore the temporary .dtrace dir for boehm-gc.o, which is first
linked via libruntime[-static].la into pedump, then into mono).
Now, a different topic would be how to let (users') assemblies place
custom probe points with a managed API, as an equivalent to the C
DTrace API used within the Mono runtime. That is, how to translate
/* hello.c */
#include "mydtrace.h"
int main() {
if (MYPROVIDER_MYPROBE_ENABLED())
MYPROVIDER_MYPROBE(42);
printf("Hello World\n");
MYPROVIDER_MYPROBE2();
return 0;
}
to something like this:
/* hello.cs */
using System;
using MyDTrace;
class Test {
static void Main() {
MyProvider myProvider = new MyProvider();
if (myProvider.MyProbeEnabled)
myProvider.MyProbe(42);
Console.WriteLine("Hello World");
myProvider.MyProbe2();
}
}
That could be interesting, for instance, for tracing a server such as
xsp/mod-mono-server.
But in that particular case, for portability reasons, it might be
smarter to do that without such managed code and special provider,
implementing method-level hooks for the 'mono' provider instead. Java
apparently has a command line option to explicitly enable method-level
USDT probes in their JIT; we'd need to evaluate whether to reuse --
trace for that or whether to keep it separate and to add a new option
to enable that feature explicitly. That's what I referred to as a
"hot" path.
There's lots of things that are imaginable and possible to implement
if we figure out how, but I suggest we start small and extend it on an
as-needed and as-contributed basis. Maybe I can contribute a shell
script to further simplify the post processing steps for Solaris,
extracting all object files for a .a library to a temporary directory
like libtool itself does, then it would be even easier for others to
add probes in random places, without needing to touch any Makefiles.
I hope some part of my explanations answers your question and sheds
some more light on my patch.
Andreas
More information about the Mono-devel-list
mailing list