[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