DTrace 0.1 Release

From CDOT Wiki
Revision as of 13:08, 18 October 2008 by Hellwolf36 (talk | contribs) (Step 4: Check for current probes)
Jump to: navigation, search


The purpose of 0.1 is to show that I am aware of how a D-Trace probe works, by using a D script to pick up on function call counts (for now) and see what it can gather. This functionality can only be tested on Mac OS X 10.5 Leopard or Open Solaris.

Step 1: Build Pre-requisites

The user is responsible for making sure that thier Mac or Solaris machine has met the requirements for building Mozilla. These instructions (Mac or OpenSolaris) must be met. It is recommended that you have at least built Mozilla at least once and are able to run it.

You must build v3.0.1 or higher of Mozilla Firefox in order to have D-Trace functionality. I used 3.0.3. Retrieve this version here

Step 2: Change your $PATH global

There is one specific header file that client.mk or configure will check for. It is called sys/sdt.h. If your current PATH cannot link to it, then not only will D-Trace not work, but Mozilla will not compile. In Mac and Solaris, this problem should be resolved by using this as your $PATH:

export PATH=/usr/include/sys:/usr/include:/opt/local/bin:/opt/local/sbin:$PATH

/usr/include/(sys) contains the sys/sdt.h header you need. The other 2 help resolve a possible issue when compiling on Mac (Your compiler may say libIDL and GLib cannot be found, this should resolve it).

Step 3: .Mozconfig file

Once you have extracted all the contents of the tar file (from Step 1), you should have a mozilla directory.

//Assuming you placed it within your home directory
$cd ~/mozilla
$vi .mozconfig

Inside the .mozconfig editor, add at least following: ac_add_options --enable-dtrace
ac_add_options --disable-tests
ac_add_options --disable-debug
ac_add_options --enable-optimize
ac_add_options --enable-application=browser

The bolded option is the one we need. This tells the build to check for D-Trace dependancies and build the necessary probes on runtime. The rest are to ensure your build goes as fast as possible, and the application in the end will consume less memory. :wq out of the file and compile Mozilla using:
make -f client.mk build or gmake -f client.mk build if you are using GNU.

Some people often omit the dtrace line from .mozconfig and run this command instead: $ configure --enable-dtrace
$ make or gmake

This works the same way. But I have seen most OpenSolaris people do this when it comes to installing patches to improve the D-Trace functionality.

Step 4: Check for current probes

It is wise that you have 2 Terminals running at this point. 1 will allow you to keep firefox running, the other will allow you to do dtrace grunt work.

In order to pick up any current probes, you must run the firefox-bin while you do these commands. Re-direct yourself to the Mozilla application you will use.

$cd dist/bin

$cd dist/Minefield.app/Contents/MacOS
You are not to use dist/bin! If you do, it will run - but it will not retrieve keyboard input.
Run the executable specified with (you may run it in Background if you wish):
./firefox-bin -profilemanager [$]

Upon running, it is wise to create yourself a seperate profile than the one you are using for Firefox. This helps if you have 2 different versions of it running at once.

To get a list of any javascript based probes that are currently running, we will use the dtrace command. For Mac users, you need superuser permissions via sudo to make this command run.

[sudo] dtrace -n 'javascript*' -l

This command will output all currently running scripts matching this naming convention. It will only display probes that are currently running, so firefox must be running in order for this command to output. The output should look something like this (Provider ID may be different):

   ID   PROVIDER            MODULE                          FUNCTION NAME
20925 javascript333    libmozjs.dylib                      js_Interpret function-args<br>
20926 javascript333    libmozjs.dylib            jsdtrace_function_args function-args<br>
20927 javascript333    libmozjs.dylib                      js_Interpret function-entry<br>
20928 javascript333    libmozjs.dylib           jsdtrace_function_entry function-entry<br>
20929 javascript333    libmozjs.dylib                      js_Interpret function-info<br>
20930 javascript333    libmozjs.dylib            jsdtrace_function_info function-info<br>
20931 javascript333    libmozjs.dylib                      js_Interpret function-return<br>
20932 javascript333    libmozjs.dylib          jsdtrace_function_return function-return<br>
20933 javascript333    libmozjs.dylib                      js_Interpret function-rval<br>
20934 javascript333    libmozjs.dylib            jsdtrace_function_rval function-rval<br>

javascript333 is the unique provider for the probes. 333 is required in case you have 2 programs running that use D-Tracing (replacing the * with the number helps limit your script). libmozjs.dylib is the Mozilla module that has the definition of these probes. Each probe has 5 categories split into 2 functions - the function itself and the interpreter.

A list of all the probe definitions can be found at this blog written by John Rice.

Step 5 - Compiling a D-Trace Script

I have written 2 DTrace scripts. The first one captures and outputs any calls found on the function-entry probe (basically the event fired when a function was entered or processed), along with how many times. The second one outputs the I/O buffer sizes your processes use.

D-Trace scripts are .d files that allow the user to interact with the existing probes and do innovative things. If a programmer tends to add new probes to the Mozilla code base, they can use a script to pick up on it to make sure it was implemented and interacted properly.

With your terminal that isn't handling Mozilla Minefield, go to your mozilla home directory and paste this code into it.

#pragma D option quiet

        printf("Tracing... Hit Ctrl-C to end.\n");

        @funcs[basename(copyinstr(arg0)), copyinstr(arg2)] = count();

        printf(" %-32s %-36s %8s\n", "FILE", "FUNC", "CALLS");
        printa(" %-32s %-36s %@8d\n", @funcs);

Quiet will tell the system to post less garbage to the screen with an exception for the print functions. The BEGIN component runs the functions upon running of the script.

The middle will pick up 2 arguments: The