Adding Dtrace Probes to Mozilla

Hi - we've been looking at adding a general framework for dynamic instrumentation to mozilla. On OpenSolaris this means dtrace probes :) The blurb from the submitted  bugzilla RFE gives you the general idea:

Proposal 

The main goal for this Dynamic Tracing Framework for Mozilla is to provide a common interface for adding instrumentation points or probes to Mozilla so its behavior can be easily observed by developers and administrators even in production systems. This framework will allow Mozilla to use the appropriate monitoring/tracing facility provided by each OS. OpenSolaris, FreeBSD and MacOS will use DTrace and other OSes can use their own respective tool.

All the gory details are up with the bug including the full proposal:

Bug 370906: [RFE] Dynamic Tracing Framework for Mozilla

Example 1 

A little sample output from Firefox built with --enable-dtrace and using the layout probes. The layout probes fire when a page is being loaded by Firefox. The phases that are triggered during the auto layout are frame construction, reflow [elements on the page need to be changed] and paint. All of these phases can be tracked by the probes, the times taken for each phase and whether one phase has triggered other phases, such as reflow causing new frame construction.

This script just counts the number and type of each phase that is triggered for a specific Presentation context. 

$ dtrace -qs layout_count.d -p `pgrep firefox-bin` -o out.txt

Snip from layout_count.d [see bug for full details]:
trace_mozilla$target:::layout-start
{
@[arg0, phaseStr[arg1], probefunc] = count();
}

Sample Output

$ cat out.txt | c++filt 
Pres Ctx Phase Count Function
153556424 [ paint ] 2 unsigned PresShell::Paint(nsIView\*,
nsIRenderingContext\*,const nsRegion)
169258584 [ frameCon ] 2 unsigned nsCSSFrameConstructor::CharacterDataChanged
(nsIContent\*,int)
140305640 [ frameCon ] 4 unsigned nsCSSFrameConstructor::ContentRemoved
(nsIContent\*,nsIContent\*,int,int)

This information is very important when tracking down hard to debug reflow bugs or when trying to understand performance timing data for specific pages. As we work with the probes we will start to look at how Firefox is interacting with the system as these phases are being triggered, such as what XServer traffic is being generated. This will be possible by combining the Firefox layout probes and the Xserver probes.

Plans

We are hacking away to improve the patch given feedback from the mozilla folks. But thought others might enjoy having a go now, so I've put down some general instructions if you are keen to try this on OpenSolaris :) We are putting in some layout probes which allow you to see the progress of frame construction, reflow and paint as a new page is loaded as a proof of concept. We will also provide a patch to add Brendan Gregg's Javascript probes in the next few days which should be an interesting adjunct to Mozilla's Javascript debugger. The hope is that others who have a lot more knowledge of the mozilla code base will start adding their own probes, once the infrastructure is in place to support them. The patch is still in review so a ways to go yet, but hopefully as others use them, the benefits will become clear. We have tried to make sure we minimize the probe impact and by default dtrace is not enabled in the build, you must build mozilla with ./configure --enable-dtrace to add any of the dtrace infrastructure.

Setup

All of the patches discussed below can be obtained from: Bug 370906

Prerequities

Getting Sources

  • Mozilla sources
    • Grab the mozilla sources from head: Mozilla CVS
    • If you need to do this from behind a firewall, you can use runsocks and set your CVS_RSH=ssh and your SOCKS5_SERVER=<socks server>
$ export CVSROOT=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot"
$ cvs login -> just hit return for password
$ cvs co mozilla

Applying Patches

  • Mozilla infrastructure + layout probe patch:
    • To get the diff patch, just go to the bug  370906 and look for "Mozilla Dynamic Tracing Framework + layout probes patch" in the Attachment table, click on it and do a save as mozilla-layout.diff
    • Apply mozilla-layout.diff downloaded from bug 370906 
$ cd mozilla
$ gpatch -p0 -i mozilla-layout.diff

Building Mozilla

  • Build mozilla
    • Setup mozilla for building:
$ export LD_LIBRARY_PATH=/usr/sfw/lib
$ export CC="/usr/bin/cc"
$ export CXX="/usr/bin/CC"
$ export CFLAGS="-xlibmil"
$ export CXXFLAGS="-xlibmil -xlibmopt -features=tmplife -norunpath"
$ export LDFLAGS="-R'\\$\\$ORIGIN:\\$\\$ORIGIN/..' -R/usr/sfw/lib"
  • Create a .mozconfig file under mozilla/.mozconfig containing the following:
ac_add_options --enable-xft
ac_add_options --disable-freetype2
ac_add_options --disable-tests
ac_add_options --disable-debug
ac_add_options --enable-svg
ac_add_options --enable-canvas
ac_add_options --enable-optimize
ac_add_options --enable-xinerama
ac_add_options --disable-auto-deps
ac_add_options --enable-application=browser
. $topsrcdir/browser/config/mozconfig
  • You must run autoconf to regenerate configure with the appropriate dtrace options; it needs to be version 2.13.
$ autoconf
$ ./configure --enable-dtrace
Note: this will generate a mozilla-trace.h from the mozilla-trace.d if one is not
present in the mozilla root directory.
$ gmake

Testing the Probes

  • The probes should now be present
    • Check Layout Probes are there.
$ cd mozilla/dist/bin
$ export LD_LIBRARY_PATH=".:$LD_LIBRARY_PATH"
$ ./firefox-bin &
$ dtrace -n 'trace_mozilla\*:::layout\*' -l

Example 2

This sample script is using the layout start and end probes to time the various layout phases as they occur when a page is loaded by Firefox. The script will print out the Presentation context for each phase [identifies which context each phase is being triggered for], which allows them to be grouped together, along with the time taken for each phase and the function which is triggering that phase.

#!/usr/sbin/dtrace -s
#pragma D option quiet

enum eLayoutPhases { EPaint, EReflow, EFrameC};
BEGIN
{
phaseStr[EPaint] = "paint";
phaseStr[EReflow] = "reflow";
phaseStr[EFrameC] = "frameCon";
}

trace_mozilla\*:::layout-start
{
self->ts[probefunc, arg0, arg1] = timestamp;
}

trace_mozilla\*:::layout-end
/self->ts[probefunc, arg0, arg1]/
{
@phase_time[arg0, phaseStr[arg1], probefunc ] =
sum((timestamp - self->ts[probefunc, arg0, arg1])/1000);
self->ts[probefunc, arg0, arg1] = 0;
}

dtrace:::END
{
printf("%10s %10s %8s %-30s \\n", "Pres Ctx", "Phase", "Time(usec)", "Function" );
printa("%10d [ %8s ] %5@d %-30s \\n", @phase_time);
}

profile:::tick-1sec
/x++ == $1/
{ exit(0);}

Sample Output

$ dtrace -qs layout_time.d -p `pgrep firefox-bin` -o out.txt
$ cat out.txt | c++filt
Pres Ctx Phase Time(usec) Function
156084568 [ frameCon ] 34 unsigned nsCSSFrameConstructor::CharacterDataChanged
(nsIContent\*,int)
141161216 [ frameCon ] 91 unsigned nsCSSFrameConstructor::ContentRemoved
(nsIContent\*,nsIContent\*,int,int)
141161216 [ frameCon ] 331 unsigned nsCSSFrameConstructor::ContentInserted
(nsIContent\*,nsIContent\*,int,nsILayoutHistoryState\*,int)
141161216 [ reflow ] 3458 unsigned PresShell::ProcessReflowCommands(int)
152558200 [ paint ] 6216 unsigned PresShell::Paint(nsIView\*,
nsIRenderingContext\*,const nsRegion )
141161216 [ paint ] 90459 unsigned PresShell::Paint(nsIView\*,
nsIRenderingContext\*,const nsRegion )

 

Comments:

Post a Comment:
Comments are closed for this entry.
About

jmr

Search

Top Tags
Categories
Archives
« July 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   
       
Today