Firefox on OSX with dtrace

Tags: , ,

This entry was posted on Friday, February 20th, 2009 at 2:00 pm and is filed under development tools, dojo, javascript. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

After seeing a great talk by Johannes Schlueter about dtrace, I want to pass on the information and give a short introduction on how to set up your (Firefox) JavaScript development environment on OSX so you can dive into dtrace and start exploring the powerful features of this tool.

Building Firefox

it is recommended to build Firefox from a release source and not from trunk since you really want to profile your app in an production environment. You can build Firefox from head though some of the plugins won’t work.

1. Building preconditions

To build firefox you need to make sure that a few modules are installed:

Xcode

If Xcode is not yet installed on your machine get a copy at http://developer.apple.com/technology/xcode.html.

Mac Ports

You need Mac Ports to make installation of the following modules much easier. Get the .dmg here http://www.macports.org/install.php

Packages for building Firefox

The remaining two packages you will need from the ports repository are “libidl” and “autoconf213″
After you have installed Mac ports open a terminal and run

$ sudo port sync
$ sudo port install libidl autoconf213

2. Download Firefox

For this blog article we will download the 3.0.6 release from ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/3.0.6/source/ – if you want to profile other firefox releases visit ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ and go to the proper VERSION/source directory.

You can get more useful information on how to download the source from trunk (mercurial) at https://developer.mozilla.org/en/Build_Documentation#Get_the_source

Once you have the source, move it into your home directory, extract it and go into the created “mozilla” directory in a shell.

$ cd ~
$ tar xf firefox-3.0.6-source.tar.bz2 
$ cd mozilla

3. Creating a build config

Create a file in your home directory ($ cd ~) with following content and save it under .mozconfig

. $topsrcdir/browser/config/mozconfig
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-ff
ac_add_options --disable-libxul
ac_add_options --enable-debug --disable-optimize
ac_add_options --enable-shared --disable-static --enable-dtrace
ac_add_options --with-macos-sdk=/Developer/SDKs/MacOSX10.5.sdk
mk_add_options MOZ_MAKE_FLAGS="-s -j4"
mk_add_options AUTOCONF=autoconf213

4. Build Firefox

Make sure you are in the directory of the downloaded firefox source – this should be the “mozilla” directory and run

$ cd mozilla
$ make -f client.mk build

5. Launch the newly build firefox

$ cd obj-ff/dist
$ open MinefieldDebug.app

Testing dtrace

Fortunately dtrace already is installed on OSX 10.5 (My machine is running on 10.5.6).
Open a new shell and open for instance google.com. After the page has loaded switch back to the shell and enter

sudo dtrace -n javascript*:::function-entry'{ @[copyinstr(arg1), copyinstr(arg2)] = count(); }' 
    -n END'{ printa("\n%-6s %-35s  %5@u", @); }'

(Note that you have to paste the code in one line!)

We are using the “function-entry” probe which will give us the possibility to inspect each function call within the javascript code. This example is fairly simple and is just showing us how many times a function got called.

Now on the Google page open the dropdown of the top menu and close it again.
Back in the shell, terminate dtrace by pressing “CTRL+C” and inspect the output.

It should look similar to this

CPU     ID                    FUNCTION:NAME
  1      2                             :END 
<null> abs                                      1
<null> autosave_disable_buttons                 1
<null> autosave_enable_buttons                  1
<null> autosave_parse_response                  1
<null> autosave_saved                           1
<null> autosave_update_preview_link             1
<null> autosave_update_slug                     1
<null> blur                                     1
<null> clearInterval                            1
<null> complete                                 1
<null> isNaN                                    1
<null> open                                     1
<null> send                                     1
<null> setInterval                              1
<null> success                                  1
<null> getResponseHeader                        2
<null> j                                        2
<null> join                                     2
<null> match                                    2
<null> parseInt                                 2
<null> removeChild                              2
<null> appendChild                              3
<null> goUpdateGlobalEditMenuItems              3
<null> goUpdatePlacesCommands                   3
<null> removeAttribute                          3
<null> setRequestHeader                         3
<null> createElement                            4
<null> toString                                 7
<null> valueOf                                  7
<null> substr                                  11
<null> isCommandEnabled                        12
<null> concat                                  13
<null> setTimeout                              15
<null> substring                               16
<null> goUpdateCommand                         24
<null> encodeURIComponent                      26
<null> getControllerForCommand                 27
<null> toLowerCase                             27
<null> getElementsByTagName                    31
<null> updatePlacesCommand                     36
<null> goSetCommandEnabled                     60
<null> setAttribute                            61
<null> split                                   64
<null> getElementById                          92
<null> apply                                  191
<null> replace                                223
<null> test                                   268
<null> exec                                   356
<null> getAttribute                           359
<null> toUpperCase                            376
<null> shift                                  482
<null> unshift                                546
<null> call                                   654
<null> indexOf                                835
<null> push                                  2329
<null> <null>                                6251

In the next blog post I will explain how we can write more complex dtrace scripts which give us deeper insight into profiling our applications performance. We merely have covered the tip of the dtrace iceberg so watch out for the next dtrace update.

Thanks Johannes for the great talk!

4 Responses to “Firefox on OSX with dtrace”

  1. Comment by periklis — February 26, 2009 @ 1:32 pm

    Hi Nicolai,
    you can use Instruments als Dtrace gui. Really nice and handy tool on OSX ;)


  2. Pingback by Uxebu.com - JavaScript addicts » Firefox on OSX with dtrace - Part II — March 2, 2009 @ 1:01 pm

    [...] the last article I have given an introduction on how to get dtrace running in your development environment, how to [...]


  3. Pingback by Pages tagged "osx" — March 4, 2009 @ 8:38 pm

    [...] bookmarks tagged osx Uxebu.com – JavaScript addicts ยป Firefox on OSX w… saved by 34 others     nejifangirl07 bookmarked on 03/04/09 | [...]


  4. Pingback by JavaScript profiling with dtrace | Dejan Ranisavljevic, web developer (PHP, MySQL, Javascript) — March 25, 2009 @ 1:37 am

    [...] Firefox on OSX with dtrace Part I Firefox on OSX with dtrace – Part II tags: javascript | # « Git bash completion [...]


Leave a Reply