<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nicholas Nethercote</title>
	<atom:link href="http://blog.mozilla.com/nnethercote/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mozilla.com/nnethercote</link>
	<description>Just another Blog.mozilla.com weblog</description>
	<lastBuildDate>Wed, 18 Nov 2009 00:11:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Nanojit test coverage</title>
		<link>http://blog.mozilla.com/nnethercote/2009/11/18/nanojit-test-coverage/</link>
		<comments>http://blog.mozilla.com/nnethercote/2009/11/18/nanojit-test-coverage/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 00:11:36 +0000</pubDate>
		<dc:creator>Nicholas Nethercote</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/nnethercote/?p=204</guid>
		<description><![CDATA[On i386, Nanojit has two basic modes of operation:  SSE, and non-SSE.  Non-SSE is for old machines that don&#8217;t support SSE instructions.  (It might actually be SSE2 instructions, I&#8217;m not sure.)  My two machines both support SSE and so the non-SSE is never exercised unless I specify the environment variable X86_FORCE_SSE=no.  Since this invocation doesn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>On i386, Nanojit has two basic modes of operation:  SSE, and non-SSE.  Non-SSE is for old machines that don&#8217;t support SSE instructions.  (It might actually be SSE2 instructions, I&#8217;m not sure.)  My two machines both support SSE and so the non-SSE is never exercised unless I specify the environment variable X86_FORCE_SSE=no.  Since this invocation doesn&#8217;t exactly roll off the fingertips, I don&#8217;t do it often.  It&#8217;s also easy to mistype, in which case the normal SSE code will be run but I probably won&#8217;t notice and so I&#8217;m testing something different to what I think I am testing.</p>
<p>I recently committed a patch (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=516348">bug 516348</a>) that broke the non-SSE mode.  (It may have also broken the SSE mode, but in a less obvious way.)  Whenever I land a patch that breaks something, I try to work out if I could have avoided the breakage through a better process.  In this case I could have, through automation.  I now have the following set of aliases and functions in my .bashrc:</p>
<pre>alias jstt_prefix="python trace-test/trace-test.py"
JSTTARGS32="--no-slow -f -x sunspider/check-date-format-tofte.js"
JSTTARGS64="$JSTTARGS32"

alias jsdtt32="                   jstt_prefix debug32/js $JSTTARGS32"
alias jsott32="                   jstt_prefix opt32/js   $JSTTARGS32"
alias jsdtt32b="X86_FORCE_SSE2=no jstt_prefix debug32/js $JSTTARGS32"
alias jsott32b="X86_FORCE_SSE2=no jstt_prefix opt32/js   $JSTTARGS32"
alias jsott64="                   jstt_prefix opt64/js   $JSTTARGS64"
alias jsdtt64="                   jstt_prefix debug64/js $JSTTARGS64"

function jsatt
{
  if [ -d debug32 ] &amp;&amp; [ -d debug64 ] &amp;&amp; [ -d opt32 ] &amp;&amp; [ -d opt64 ] ; then
    cd debug32 &amp;&amp; mq &amp;&amp; cd .. &amp;&amp; \
    cd debug64 &amp;&amp; mq &amp;&amp; cd .. &amp;&amp; \
    cd opt32 &amp;&amp; mq &amp;&amp; cd .. &amp;&amp; \
    cd opt64 &amp;&amp; mq &amp;&amp; cd ..

    if [ $? -eq 0 ] ; then
      echo
      echo "debug32"          &amp;&amp; jsdtt32   &amp;&amp; echo
      echo "debug32 (no SSE)" &amp;&amp; jsdtt32b  &amp;&amp; echo
      echo "debug64"          &amp;&amp; jsdtt64   &amp;&amp; echo
      echo "opt32"            &amp;&amp; jsott32   &amp;&amp; echo
      echo "opt32 (no SSE)"   &amp;&amp; jsott32b  &amp;&amp; echo
      echo "opt64"            &amp;&amp; jsott64   &amp;&amp; echo
    fi
  else
    echo "missing one of debug32/debug64/opt32/opt64"
  fi
}</pre>
<p>The code is boring.  For those reading closely, it relies on the fact that I always put different builds in the directories debug32/, opt32/, debug64/, opt64/.  And I skip check-data-format-tofte.js because it fails if you&#8217;re in a non-US timezone, see <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=515254">bug 515214</a>.</p>
<p>I already had &#8216;jsdtt32&#8242; et al, each of which tests a single configuration.  But now with a single command &#8216;jsatt&#8217; (which is short for &#8220;JavaScript All trace-tests&#8221;) I can run the JS trace-tests on 6 different configurations on a single x86-64 machine: 32-bit debug (SSE), 32-bit debug (non-SSE), 64-bit debug, 32-bit optimised (SSE), 32-bit optimised (non-SSE), 64-bit optimised.  And it builds them to make sure they&#8217;re all up-to-date.</p>
<p>It&#8217;s only a small process change for me, but it means that it&#8217;s unlikely I will break any of these configurations in the future, or at least, not in a way that shows up in the trace-tests.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/nnethercote/2009/11/18/nanojit-test-coverage/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Valgrind and Mac OS 10.6</title>
		<link>http://blog.mozilla.com/nnethercote/2009/09/02/valgrind-and-mac-os-10-6/</link>
		<comments>http://blog.mozilla.com/nnethercote/2009/09/02/valgrind-and-mac-os-10-6/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 23:11:39 +0000</pubDate>
		<dc:creator>Nicholas Nethercote</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Valgrind]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/nnethercote/?p=176</guid>
		<description><![CDATA[A new entry in the annals of unfortunate software release dates:

On August 19, Valgrind 3.5.0 was released. It added support for Mac OS 10.5.
On August 28, Mac OS 10.6 was released.
Valgrind 3.5.0 does not support Mac OS 10.6.

If you try to install Valgrind on a machine running Mac OS 10.6, it will fail at configure-time.  [...]]]></description>
			<content:encoded><![CDATA[<p>A new entry in the annals of unfortunate software release dates:</p>
<ul>
<li>On August 19, Valgrind 3.5.0 was released. It added support for Mac OS 10.5.</li>
<li>On August 28, Mac OS 10.6 was released.</li>
<li>Valgrind 3.5.0 does not support Mac OS 10.6.</li>
</ul>
<p>If you try to install Valgrind on a machine running Mac OS 10.6, it will fail at configure-time.  If you hack the configure file appropriately so that the install completes, Valgrind will run but crash quickly on any program.  <a href="https://bugs.kde.org/show_bug.cgi?id=205241">Bug 205241</a> has the details.  Greg Parker says he has a series of patches to make Valgrind work and he&#8217;s just waiting for the open source release of xnu (the core of Mac OS X) before making them public.  With some luck, these fixes will make it into Valgrind 3.5.1 relatively soon.</p>
<p>However, once that&#8217;s fixed, there&#8217;s another problem.  Mac OS 10.6 uses 64-bit executables by default.  In comparison, 10.5 uses 32-bit executables by default, even though it&#8217;s capable of creating and running 64-bit executables.  Unfortunately Valgrind&#8217;s support for 64-bit executables on Mac OS X isn&#8217;t very good.  The main problem is that start-up is sloooooow, which means that even Hello World takes over four seconds to run on my MacBook Pro.  Fixing this one will be harder, as it will require reworking the Mac OS X start-up sequence.  <a href="http://bugs.kde.org/show_bug.cgi?id=205938">Bug 205938</a> is tracking this problem.</p>
<p>Related to this: does anyone know if there is an easy way to have both 10.5 and 10.6 installed on a single machine?  That would be a big help when it comes to developing and testing Valgrind&#8217;s Mac OS X support.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/nnethercote/2009/09/02/valgrind-and-mac-os-10-6/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>&#8220;No-else-after-return&#8221; considered harmful</title>
		<link>http://blog.mozilla.com/nnethercote/2009/08/31/no-else-after-return-considered-harmful/</link>
		<comments>http://blog.mozilla.com/nnethercote/2009/08/31/no-else-after-return-considered-harmful/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 00:28:56 +0000</pubDate>
		<dc:creator>Nicholas Nethercote</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Correctness]]></category>
		<category><![CDATA[Cplusplus]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/nnethercote/?p=165</guid>
		<description><![CDATA[(Update below)
At the time of writing this, the Mozilla Coding Style guidelines have this recommendation under &#8220;General C/C++ Practices&#8221;:
Don&#8217;t put an else right after a return. Delete the else, it&#8217;s unnecessary and increases indentation level.
I can appreciate this in some circumstances, such as when checking for an error case early in a long function:
void f()
{
 [...]]]></description>
			<content:encoded><![CDATA[<p><strong>(Update below)</strong></p>
<p>At the time of writing this, the<a href="https://developer.mozilla.org/En/Developer_Guide/Coding_Style"> Mozilla Coding Style guidelines</a> have this recommendation under &#8220;General C/C++ Practices&#8221;:</p>
<blockquote><p>Don&#8217;t put an else right after a return. Delete the else, it&#8217;s unnecessary and increases indentation level.</p></blockquote>
<p>I can appreciate this in some circumstances, such as when checking for an error case early in a long function:</p>
<pre>void f()
{
    if (errorcase())
        return;

    a();
    b();
    c();
    d();
}</pre>
<p>But as a blanket guideline I think it&#8217;s misguided because it promotes an impure style of programming.  And by &#8220;impure&#8221; here I mean the opposite of &#8220;pure&#8221; in <a href="http://en.wikipedia.org/wiki/Pure_function">this</a> <a href="http://en.wikipedia.org/wiki/Purely_functional">sense</a>, i.e. &#8220;free from side-effects and other such error-prone junk&#8221;.  Let&#8217;s consider a simple example:  the max() function.  Here&#8217;s a way to write it that is quite sensible, in my opinion:</p>
<pre>int max(int a, int b)
{
    if (a &gt; b)
        return a;
    else
        return b;
}</pre>
<p>But this violates the no-else-after-return guideline.  The Mozilla way to write this is like so:</p>
<pre>int max(int a, int b)
{
    if (a &gt; b)
        return a;
    return b;
}</pre>
<p>(I&#8217;m not exaggerating, see <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=513379#c11">this comment</a> and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=513379#c13">this comment</a> from Mozilla&#8217;s VP of Engineering and CTO respectively, about an example very similar to this.)</p>
<p>Urk.  That&#8217;s horrible.  Any time you&#8217;re using an &#8216;if&#8217; without a corresponding &#8216;else&#8217;, you&#8217;re relying on an impure feature &#8212; you must be doing something with a side-effect in the &#8216;then&#8217; branch, or some kind of impure control flow.  Mozilla&#8217;s coding guidelines insist that we write max(), a pure function, in an impure way.  Also, it&#8217;s just harder to read because the two return statements have different indentation levels despite the fact that they are closely related.</p>
<p>In this case there&#8217;s a way around the problem:</p>
<pre>
<pre>int max(int a, int b)
{
    return (a &gt; b ? a : b);
}</pre>
</pre>
<p>Even though C&#8217;s if-then-else expression syntax is awful, it&#8217;s a better way to do it.</p>
<p>In general, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=513379#c21">statements suck</a>, expressions rule.  Even in a language like C/C++ you can do something approaching functional programming by avoiding statements where possible.  In a tiny example like max() the difference may seem trivial, but in bigger examples the difference becomes more important.  Consider the following code from Nanojit&#8217;s register allocator which picks a register by looking at the free registers, the registers that are allowed to be used, and possibly the preferred registers.  You don&#8217;t have to understand it closely, but it helps to know that RegisterMask is just a bitfield with one bit per register.</p>
<pre>Register Assembler::registerAlloc(RegisterMask allow)
{
    RegAlloc &amp;regs = _allocator;
    RegisterMask prefer = SavedRegs &amp; allow;
    RegisterMask free = regs.free &amp; allow;

    RegisterMask set = prefer;
    if (set == 0) set = allow;

    if (free)
    {
        // at least one is free
        set &amp;= free;

        // ok we have at least 1 free register so let's try to pick
        // the best one given the profile of the instruction
        if (!set)                                                             
        {
            // desired register class is not free so pick first of any class
            set = free;
        }
        NanoAssert((set &amp; allow) != 0);
        Register r = nRegisterAllocFromSet(set);
        regs.used |= rmask(r);
        return r;
    }

    // ... more code here ...
}</pre>
<p>I find this code incredibly hard to understand.  There are three &#8216;ifs&#8217; that lack &#8216;elses&#8217;, so it relies heavily on state updates to do its work.  In fact, in order to understand it, I ended up rewriting it in a more pure style, by using a sequence of small refactorings:</p>
<pre>Register Assembler::registerAlloc(RegisterMask allow)
{
    RegAlloc &amp;regs = _allocator;
    RegisterMask allowedAndFree = allow &amp; regs.free;

    if (allowedAndFree)
    {
        // At least one usable register is free -- no need to steal.  
        // Pick a preferred one if possible.
        RegisterMask preferredAndFree = allowedAndFree &amp; SavedRegs;
        RegisterMask set = ( preferredAndFree ? preferredAndFree : allowedAndFree );
        Register r = nRegisterAllocFromSet(set);
        regs.used |= rmask(r);
        return r;
    }
<pre>    // ... more code here ...
}</pre>
</pre>
<p>There&#8217;s now only a single &#8216;if&#8217; lacking an &#8216;else&#8217;, and it turns out even that can be removed by putting the &#8220;&#8230; more code here &#8230;&#8221; part into an else branch, and then the &#8216;return r;&#8217; can be moved to the end of the function.</p>
<p>The code is now comprehensible &#8212; it picks a register that is free and allowed, and preferred as well if possible.</p>
<p>Part of the art of programming involves knowing when to avoid using a language feature.  Everybody knows that &#8216;goto&#8217; is occasionally highly useful, but should be avoided whenever something less dangerous (a for-loop, a while-loop, a &#8216;break&#8217; statement) can be used.  And everybody knows it because everybody is taught it.  But programmers aren&#8217;t taught to avoid unnecessary side-effects&#8230; at least, I wasn&#8217;t, certainly not via examples such as those I&#8217;ve given above.  I&#8217;ve only come to realise these things as I&#8217;ve switched several times between using C/C++ and some pure functional languages over the years, and come to appreciate how purity helps make programs more readable and less error-prone.</p>
<p>To come full circle, I&#8217;d like to see the no-else-after-return guideline removed from the Mozilla style guide, or at the very least, be qualified in a way that allows the cases I&#8217;ve argued for.  I&#8217;d also love to see a guideline (with examples) added such as &#8220;prefer expressions to statements&#8221;.</p>
<p><strong>Update:</strong></p>
<p>(The arguments had the wrong names in the initial post, I&#8217;ve fixed them now.)</p>
<p>All three versions of max() are pure, because it&#8217;s possible to combine impure pieces of code (such as an else-less if) into a pure piece of code.  So I&#8217;ll augment my recommendation: pure code is preferable, and furthermore,<em> </em>given that C/C++ makes it so easy to write impure code, it&#8217;s preferable that pure code <em>be obviously pure.</em> I argue that the 3rd version of max() with the ?: operator is the most obviously pure, because a ?: is pure if its operands are pure.  In comparison, it&#8217;s harder to tell if an if-then-else is pure (although this case is still pretty easy thanks to the matching return statements).  And an if-without-else almost never results in pure code;  the max() example above is a rare exception.</p>
<p>I also omitted a fourth formulation of max:</p>
<pre>int max(int a, int b)
{
    int m;
    if (a &gt; b)
        m = a;
    else
        m = b;
    return m;
}</pre>
<p>For this very simple case, such a formulation is overkill.  But if the &#8216;then&#8217; and &#8216;else&#8217; cases are more complicated it makes more sense.  (Furthermore, much of this discussion should be thought of in more complex cases, as these kinds of small decision can make a bigger difference then.)  This version also doesn&#8217;t violate the no-else-after-return rule.  So perhaps that rule isn&#8217;t as bad as I thought, if only because it&#8217;s easier to work around than I thought&#8230; but I still think rewriting the 1st version of max() into the 2nd version is a bad idea.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/nnethercote/2009/08/31/no-else-after-return-considered-harmful/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Valgrind 3.5.0 has been released</title>
		<link>http://blog.mozilla.com/nnethercote/2009/08/20/valgrind-3-5-0-has-been-released/</link>
		<comments>http://blog.mozilla.com/nnethercote/2009/08/20/valgrind-3-5-0-has-been-released/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 07:12:00 +0000</pubDate>
		<dc:creator>Nicholas Nethercote</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Valgrind]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/nnethercote/?p=158</guid>
		<description><![CDATA[Valgrind 3.5.0 has been released!  It&#8217;s the first release that supports Mac OS X.  It also adds a number of other new features and a whole lot of bug-fixes.  See the release notes for details.  Many thanks to everyone who contributed to this release.
]]></description>
			<content:encoded><![CDATA[<p>Valgrind 3.5.0 has been <a href="http://valgrind.org/downloads/current.html">released</a>!  It&#8217;s the first release that supports Mac OS X.  It also adds a number of other new features and a whole lot of bug-fixes.  See the <a href="http://valgrind.org/docs/manual/dist.news.html">release notes</a> for details.  Many thanks to everyone who contributed to this release.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/nnethercote/2009/08/20/valgrind-3-5-0-has-been-released/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>How I Work on Tracemonkey</title>
		<link>http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/</link>
		<comments>http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 07:10:28 +0000</pubDate>
		<dc:creator>Nicholas Nethercote</dc:creator>
				<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[Tracemonkey]]></category>
		<category><![CDATA[Work habits]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/nnethercote/?p=146</guid>
		<description><![CDATA[After six months of working on Tracemonkey, I&#8217;ve built up a particular workflow &#8212; how I use Mercurial, arrange my workspaces, run tests, and commit code.  I thought it would be worth describing this in case it helps other developers improve their workflow, or perhaps so they can give me ideas on how to improve [...]]]></description>
			<content:encoded><![CDATA[<p>After six months of working on Tracemonkey, I&#8217;ve built up a particular workflow &#8212; how I use Mercurial, arrange my workspaces, run tests, and commit code.  I thought it would be worth describing this in case it helps other developers improve their workflow, or perhaps so they can give me ideas on how to improve my own workflow.</p>
<h3>Workspace Structure</h3>
<p>I have two machines, an Ubuntu Linux desktop and a Mac laptop.  For both machines I use the same workspace structure.  All my Mozilla work is in a directory ~/moz/.  At any one time I have up to 10 workspaces.  ~/moz/ws0/ always contains an unmodified clone of the tracemonkey repository, created like so:</p>
<pre>hg clone http://hg.mozilla.org/tracemonkey/ ~/moz/ws0</pre>
<p>Workspaces ~/moz/ws1 through to ~/moz/ws9 are local clones of ~/moz/ws0/ in which I make modifications.  I create these workspaces like this:</p>
<pre>hg clone ~/moz/ws0 ~/moz/wsN</pre>
<p>Local hg clones are much cheaper than ones done over the network.  On my Linux box it takes about 45 seconds, on my Mac somewhere over 2 minutes;  it seems that laptops have slower hard disks than desktops.  In comparison, cloning hg.mozilla.org/tracemonkey/ can take anywhere from 5 to 30 minutes or more (I don&#8217;t know why there&#8217;s so much variation there).</p>
<p>I mostly work with the Javascript shell, called &#8216;js&#8217;, so I do most of my work in ~/moz/wsN/js/src/.  There are three ways I commonly build &#8216;js&#8217;.</p>
<ul>
<li>Debug builds go in ~/moz/wsN/js/src/debug/.  I use these for most of my development and testing.</li>
<li>Optimised builds go in ~/moz/wsN/js/src/opt/.  I use these for measuring performance.</li>
<li>Optimised builds with symbols go in ~/moz/wsN/js/src/optg/.  I use these with Cachegrind, which needs optimised code with symbols to be useful.</li>
</ul>
<p>I have a number of bash aliases I use to move around these directories:</p>
<pre>alias m="cd ~/moz/"
alias m0="cd ~/moz/ws0/"
alias j0="cd ~/moz/ws0/js/src/"
alias j0d="cd ~/moz/ws0/js/src/debug/"
alias j0o="cd ~/moz/ws0/js/src/opt/"</pre>
<p>and so on for the remaining workspaces ws1 through ws9.  I have a common bash config file that I use on both my machines;  whenever I change it I copy it to the other machine.  This is a manual process, which is not ideal, but in practice it works well enough.</p>
<p>I find nine workspaces for making changes is enough to cover everything I&#8217;m doing;  if I find myself needing more it&#8217;s because some of the existing ones have stagnated and I need to do some cleaning up.</p>
<h3>Building &#8216;js&#8217;</h3>
<p>I have three scripts, js_conf_debug, js_conf_opt, js_conf_optg, which configure and build from scratch.  Here is js_conf_debug, the others are similar:</p>
<pre>#! /bin/sh

if [ -z $1 ] ; then
    echo "usage: $0 &lt;dirname&gt;"
elif [ -d $1 ] ; then
    echo "directory $1 already exists"
else
    autoconf2.13
    mkdir $1
    cd $1
    CC='gcc -m32' CXX='g++ -m32' AR=ar ../configure \
        --enable-debug --disable-optimize --target=i686-pc-linux-gnu
    make --quiet -j 2
fi</pre>
<p>These are scripts rather than bash aliases or functions because they are quite different on the Linux machine and the Mac.</p>
<p>I also have this alias for incremental builds:</p>
<pre>alias mq="make --quiet -j 2"</pre>
<h3>Testing &#8216;js&#8217;</h3>
<p>The program I run most is trace-test.js.  So much so that I have more aliases for it:</p>
<pre>alias jsott="time opt/js -j trace-test.js"
alias jsdtt="time debug/js -j trace-test.js"</pre>
<p>I don&#8217;t need an alias for the optg build because that&#8217;s only used with Cachegrind, which I run in a different way (see below).</p>
<p>I run the JS unit test with the following script:</p>
<pre>function js_regtest
{
    x=$1
    y=$2
    if [ -z $x ] || [ -z $y ] ; then
        echo "usage: js_regtest &lt;ws-number-1&gt; &lt;ws-number-2&gt;"
    else
        xdir=$HOME/moz/ws$x/js/src/debug
        ydir=$HOME/moz/ws$y/js/src/debug
        echo "############################"
        echo "## COMPILING $xdir"
        echo "############################"
        cd $xdir &amp;&amp; mq
        echo "############################"
        echo "## COMPILING $ydir"
        echo "############################"
        cd $ydir &amp;&amp; mq
        cd $ydir/../../tests
        echo "############################"
        echo "## TESTING $xdir"
        echo "############################"
        time jsDriver.pl \
            -k \
            -e smdebug \
            --opt '-j' \
            -L spidermonkey-n.tests slow-n.tests \
            -f base.html \
            -s $xdir/js &amp;&amp; \
        echo "############################"
        echo "## TESTING $ydir"
        echo "############################"
        time jsDriver.pl \
             -k \
             -e smdebug \
             --opt '-j' \
             -L spidermonkey-n.tests slow-n.tests \
             -L base-failures.txt \
             -s $ydir/js
    fi
}</pre>
<p>An example invocation would be:</p>
<pre>js_regtest 0 3</pre>
<p>The above invocation first ensures a debug &#8216;js&#8217; is built in workspaces 0 and 3.  Then it runs ~/moz/ws0/js/src/debug/js in order to get the baseline failures, which are put in base-failures.txt.  Then it runs ~/moz/ws3/js/src/debug/js and compares the results against the baseline.  The -L lines skip the tests that are really slow;  without them it takes hours to run.  I time each invocation just so I always know roughly how long it takes;  it&#8217;s a bit over 10 minutes to do both runs.  It assumes that workspace 0 and 3 correspond to the same hg revision;  perhaps I could automate that to guarantee it but I haven&#8217;t (knowingly) got that wrong yet so haven&#8217;t bothered to do so.</p>
<h3>Timing &#8216;js&#8217;</h3>
<p>I time &#8216;js&#8217; by running SunSpider.  I obtained it like so:</p>
<pre>svn http://svn.webkit.org/repository/webkit/trunk/SunSpider ~/moz/SunSpider</pre>
<p>I haven&#8217;t updated it in a while, I hope it hasn&#8217;t changed recently!</p>
<p>I run it with this bash function:</p>
<pre>function my_sunspider
{
    x=$1
    y=$2
    n=$3
    if [ -z $x ] || [ -z $y ] || [ -z $n ] ; then
        echo "usage: my_sunspider &lt;ws-number-1&gt; &lt;ws-number-2&gt; &lt;number-of-runs&gt;"
    else
        for i in $x $y ; do
            dir = $HOME/moz/ws$i/js/src/opt
            cd $dir || exit 1
            make --quiet || exit 1
            cd ~/moz/SunSpider
            echo "############################"
            echo "####### TESTING ws$i #######"
            echo "############################"
            time sunspider --runs=$n --args='-j' --shell $dir/js &gt; opt$i
         done

         my_sunspider_compare_results $x $y
    fi
}

function my_sunspider_compare_results
{
    x=$1
    y=$2
    if [ -z $x ] || [ -z $y ] ; then
        echo "usage: my_sunspider_compare_results &lt;ws-number-1&gt; &lt;ws-number-2&gt;"
    else
        sunspider-compare-results \
            --shell $HOME/moz/ws$x/js/src/opt/js opt$x opt$y
    fi
}</pre>
<p>An invocation like this:</p>
<pre>my_sunspider 0 3 100</pre>
<p>will ensure that optimised builds in both workspaces are present, and then compare them by doing SunSpider 100 runs.  That usually gives what SunSpider claims as +/-0.1% variation (I don&#8217;t believe it, though).  On my Mac this takes about 3.5 minutes, and 100 runs is enough that the results are fairly reliable, certainly more so than the default of 10 runs.  But when testing a performance-affecting change I like to do some timings, wait until a few more patches have landed in the tree, then update and rerun the timings &#8212; on my Mac I see variations of 5-10ms regularly due to minor code differences.  Timing multiple versions like this gives me a better idea of whether a timing difference is real or not.  Even then, it&#8217;s still not easy to know for sure, and this can be frustrating when trying to work out if an optimisation I applied is really giving a 5ms speed-up or not.</p>
<p>On my Linux box, I have to use 1000 runs to get +/-0.1% variation.  This takes about 25 minutes, so I rarely do performance-related work on this machine.  I don&#8217;t know why Linux causes greater timing variation.</p>
<h3>Profiling &#8216;js&#8217; with Cachegrind</h3>
<p>I run Cachegrind on &#8216;js&#8217; running SunSpider with this bash function:</p>
<pre>function cg_sunspider
{
    x=$1
    y=$2
    if [ -z $x ] || [ -z $y ] ; then
        echo "usage: cg_sunspider &lt;ws-number-1&gt; &lt;ws-number-2&gt;"
    else
        for i in $x $y ; do
            dir = $HOME/moz/ws$i/js/src/optg
            cd $dir || exit 1
            make --quiet || exit 1
            cd ~/moz/SunSpider
            time valgrind --tool=cachegrind --branch-sim=yes --smc-check=all \
                --cachegrind-out-file=cachegrind.out.optg$i \
                --auto-run-dsymutil=yes \
                $dir/js `cat ss0-args.txt`
            cg_annotate --auto=yes cachegrind.out.optg$i &gt; ann-optg$i
        done
    fi
}</pre>
<p>ss0-args.txt contains this text:</p>
<pre>-j -f tmp/sunspider-test-prefix.js -f resources/sunspider-standalone-driver.js</pre>
<p>What this does is run just the main SunSpider program, once, avoiding all the start-up processes and all that.  This is important for Cachegrind &#8212; it means that I can safely use &#8211;cachegrind-out-file to name a specific file, which is not safe if running Cachegrind on a program involving multiple processes.   (I think this is slightly dangerous&#8230; if you run &#8217;sunspider &#8211;ubench&#8217; it seems to change one of the above .js files and you have to rerun SunSpider normally to get them back to normal.)  I use &#8211;branch-sim=yes because I often find it to be useful; at least twice recently it has helped me identify performance problems.</p>
<p>If I want to focus on a particular Cachegrind statistic, e.g. D2mr (level 2 data read misses) or Bim (indirect branch mispredictions) then I rerun cg_annotate like this:</p>
<pre>cg_annotate --auto=yes --show=I2mr --sort=I2mr cachegrind.out.optgN &gt; ann-optgN-I2mr</pre>
<h3>Profiling &#8216;js&#8217; with Shark</h3>
<p>To profile &#8216;js&#8217; with Shark, I use SunSpider&#8217;s &#8211;shark20 and &#8211;test options.  I don&#8217;t have this automated yet, I probably should.</p>
<h3>Managing Changes with Mercurial</h3>
<p>Most of my changes are not that large, so I leave them uncommitted in a workspace.  This is primitive, but has one really nice feature:  when pulling and updating, hg merges the changes and marks conflicts in the nice &#8220;&lt;&lt;&lt;&#8221; &#8220;&gt;&gt;&gt;&#8221; way.</p>
<p>In comparison, with Mercurial queues (which I tried for a while) you have to pop your patches, update, then push them, and it uses &#8216;patch&#8217; to do the merging.  And I hate &#8216;patch&#8217; because conflicted areas tend to be larger, and because they go in a separate reject file rather than being inserted inline.</p>
<p>I also avoid doing local commits unless I&#8217;m working on something really large just because the subsequent merging is difficult (at least, I think it&#8217;s difficult;  my Mercurial knowledge still isn&#8217;t great).  In that case I do local commits until the change is finished, then apply the patch (using &#8216;hg diff&#8217; and &#8216;patch&#8217;) in a single hit to a newly cloned tree &#8212; given Mozilla&#8217;s use of Bugzilla, the change will have to be a single patch anyway so this aggregation step has to happen at some point.</p>
<h3>Pre-push Checklist</h3>
<p>Before landing any patch, I do my best to work through the following check-list.  I created this list recently after having to back out several commits due to missing one of the above steps;  I give examples of breakage I&#8217;ve caused in square brackets.</p>
<ul>
<li>Ensure there are no new compiler warnings for &#8216;js&#8217; for optimised and debug builds.  [I managed to introduce some warnings on an optimised build recently for what was supposedly a whitespace-only change!]</li>
<li>Ensure &#8216;js&#8217; runs trace-test.js without failures, for optimised builds, debug builds, debug builds with TMFLAGS=full (to test the verbose output) under Valgrind (to test for memory errors).  [I've had to back out several patches due to breaking TMFLAGS=full]</li>
<li>Ensure lirasm builds and passes its tests for both optimised and debug builds.  [I've forgotten this numerous times, leaving lirasm in a broken state, which is why I created <a href="http://https://bugzilla.mozilla.org/show_bug.cgi?id=503449">bug 503449</a>].</li>
<li>Ensure unit tests pass with a debug build.  [Amusingly enough, I don't think I've ever caused breakage by forgetting this step!]</li>
<li>(For any commit that might affect performance) Check SunSpider timings with an optimised build.</li>
<li>(For complex changes) Check the patch on the try servers. (Nb: they run optimised builds, so will miss assertion failures among other things)</li>
<li>(For changes affecting the ARM backend) Check the patch builds and runs trace-test.js (using a debug build) on my virtual qemu+ARM/Linux machine.</li>
<li>Check tinderbox to make sure the tree is open for commits.  [When the tree is closed, there's no mechanism that actually prevents you from committing.  I had to back-out a patch during a tinderbox upgrade because of this.]</li>
</ul>
<p>It&#8217;s quite a list, and I don&#8217;t usually do anything with a browser build, when I probably should, so that would make it even longer.  And there are other things to get wrong&#8230; for example, I never test the &#8211;disable-jit configuration and I broke it once.</p>
<h3>Pushing</h3>
<p>When I&#8217;m ready to push a change, I make sure my workspaces are up-to-date with respect to the Mozilla repo.  I then commit the change to my modified repo, then push it from there into ~/moz/ws0/, then check &#8216;hg outgoing -p&#8217; on that repo to make sure it looks ok, and then push to the Mozilla repo from there.  I try to do this quickly so that no-one else lands something in the meantime;  this has only happened to me once and I tried to use &#8216;hg rollback&#8217; to undo my local changes which I think should have worked but seemingly didn&#8217;t.</p>
<h3>Post-push Checklist</h3>
<p>After committing, I do these steps:</p>
<ul>
<li>Mark the bug&#8217;s &#8220;whiteboard&#8221; field as &#8220;fixed-in-tracemonkey&#8221;.</li>
<li>Put a link to the commit in a comment for the bug, of the form http://hg.mozilla.org/tracemonkey/rev/&lt;revhash&gt;/.  I always test the link before submitting the comment.</li>
</ul>
<h3>Conclusions</h3>
<p>That&#8217;s a lot of stuff.  Two of my more notable conclusions are:</p>
<ul>
<li>Automation is a wonderful thing.  In particular, having scripts for the complicated tasks (e.g. running the unit tests, running sunspider, running sunspider under Cachegrind) has saved me lots of time and typing (and lots of head-scratching and re-running when I realised I forgot some command line option somewhere).  And this automation was made much easier once I settled on a standard workspace+build layout.</li>
<li>The pre-push checklist is both disconcertingly long and disconcertingly incomplete.  And I had to work it out almost entirely by myself &#8212; I&#8217;m not aware of any such check-list documented anywhere else.  Having lots of possible configurations really hurts testability.  I&#8217;m not sure how to improve this.</li>
</ul>
<p>If you made it this far, congratulations!  That was pretty dry, especially if you&#8217;re not a Tracemonkey developer.  I&#8217;d love to hear suggestions for improving what I&#8217;m doing.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/nnethercote/2009/07/27/how-i-work-on-tracemonkey/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Valgrind + Mac OS X update (July 17, 2009)</title>
		<link>http://blog.mozilla.com/nnethercote/2009/07/17/valgrind-mac-os-x-update-july-17-2009/</link>
		<comments>http://blog.mozilla.com/nnethercote/2009/07/17/valgrind-mac-os-x-update-july-17-2009/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 23:37:02 +0000</pubDate>
		<dc:creator>Nicholas Nethercote</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Valgrind]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/nnethercote/?p=139</guid>
		<description><![CDATA[We&#8217;re now in the preparation phase for the 3.5.0 release of Valgrind, which will be the first release with Mac OS X support.  We&#8217;ve absorbed some Mozilla culture in the Valgrind development process &#8212; we&#8217;re now using Bugzilla much more effectively.  We have 17 open blockers (and 18 closed blockers), and 41 open &#8220;wanted&#8221; bugs [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re now in the preparation phase for the 3.5.0 release of Valgrind, which will be the first release with Mac OS X support.  We&#8217;ve absorbed some Mozilla culture in the Valgrind development process &#8212; we&#8217;re now using Bugzilla much more effectively.  We have <a href="https://bugs.kde.org/buglist.cgi?query_format=advanced&amp;short_desc_type=allwordssubstr&amp;short_desc=&amp;product=valgrind&amp;target_milestone=blocking3.5.0&amp;long_desc_type=substring&amp;long_desc=&amp;bug_file_loc_type=allwordssubstr&amp;bug_file_loc=&amp;keywords_type=allwords&amp;keywords=&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;emailassigned_to1=1&amp;emailtype1=substring&amp;email1=&amp;emailassigned_to2=1&amp;emailreporter2=1&amp;emailcc2=1&amp;emailtype2=substring&amp;email2=&amp;bugidtype=include&amp;bug_id=&amp;votes=&amp;chfieldfrom=&amp;chfieldto=Now&amp;chfieldvalue=&amp;cmdtype=doit&amp;order=Reuse+same+sort+as+last+time&amp;field0-0-0=noop&amp;type0-0-0=noop&amp;value0-0-0=">17 open blockers</a> (and 18 closed blockers), and <a href="https://bugs.kde.org/buglist.cgi?query_format=advanced&amp;short_desc_type=allwordssubstr&amp;short_desc=&amp;product=valgrind&amp;target_milestone=wanted3.5.0&amp;long_desc_type=substring&amp;long_desc=&amp;bug_file_loc_type=allwordssubstr&amp;bug_file_loc=&amp;keywords_type=allwords&amp;keywords=&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;emailassigned_to1=1&amp;emailtype1=substring&amp;email1=&amp;emailassigned_to2=1&amp;emailreporter2=1&amp;emailcc2=1&amp;emailtype2=substring&amp;email2=&amp;bugidtype=include&amp;bug_id=&amp;votes=&amp;chfieldfrom=&amp;chfieldto=Now&amp;chfieldvalue=&amp;cmdtype=doit&amp;order=Reuse+same+sort+as+last+time&amp;field0-0-0=noop&amp;type0-0-0=noop&amp;value0-0-0=">41 open &#8220;wanted&#8221; bugs</a> (and 7 closed ones).  Any contributions towards fixing these bugs is most welcome!  We&#8217;re hoping to release in early August.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/nnethercote/2009/07/17/valgrind-mac-os-x-update-july-17-2009/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>What I currently hate most about C++</title>
		<link>http://blog.mozilla.com/nnethercote/2009/06/19/what-i-currently-hate-most-about-c/</link>
		<comments>http://blog.mozilla.com/nnethercote/2009/06/19/what-i-currently-hate-most-about-c/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 04:37:54 +0000</pubDate>
		<dc:creator>Nicholas Nethercote</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Correctness]]></category>
		<category><![CDATA[Cplusplus]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/nnethercote/?p=130</guid>
		<description><![CDATA[Everyone knows that global variables are bad and should be avoided wherever possible.  Why?  Because each global variable is, in effect, an implicit argument to every function that can see the global variable.  The same thing is true of any non-local state.
And the presence of non-local state means that you can&#8217;t reason locally about your [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone knows that global variables are bad and should be avoided wherever possible.  Why?  Because each global variable is, in effect, an implicit argument to every function that can see the global variable.  The same thing is true of any non-local state.</p>
<p>And the presence of non-local state means that you can&#8217;t reason locally about your code.  That makes your code more complex, and complex code is likely to have more defects.</p>
<p>And the thing I hate about C++ (and other object-oriented languages) is that it vigorously encourages non-local state.</p>
<h3>Non-local state within classes</h3>
<p>First, of all, C++ encourages (nay, forces) non-local state within classes, because all class methods have access to all fields within a class, even the ones they don&#8217;t need to.  In other words, every class field is an implicit argument to every class method.  This can work well for, let&#8217;s say, a &#8220;Date&#8221; class, because the number of fields is small, and most class methods will access most fields.</p>
<p>But problems appear when classes grow larger, when they start to look like what would be a whole module in a non-OO language like C.  For example, Nanojit, the compiler core in TraceMonkey, contains a class called Assembler, which encapsulates the translation of Nanojit&#8217;s low-level intermediate representation (called &#8220;LIR&#8221;) to assembly code.  If you exclude members that are only included when debugging is enabled, there are 18 data fields and 102 methods.  And some of those 18 data fields are pointers to objects that are themselves complex.</p>
<p>Let&#8217;s consider a single field, _thisfrag, which holds a fragment of LIR code. It gets set via an argument passed into the method beginAssembly().  It then gets overwritten &#8212; but with the same value! &#8212; via an argument passed into the method assemble().  It is accessed directly in only 7 of those 103 methods:</p>
<ul>
<li>assemble(): which increments _thisfrag-&gt;compileNbr</li>
<li>gen(), printActivationState(), asmspilli(): which use _thisfrag-&gt;lirbuf-&gt;names, but only when verbose output is asked-for</li>
<li>assignSavedRegs(), reserveSavedRegs(), assignParamRegs(): where parts of _thisfrag-&gt;lirbuf are read</li>
</ul>
<p>And that&#8217;s just one example, which I chose because I&#8217;d been thinking about this problem and then just this morning I had to hunt down all those uses of _thisfrag in order to understand its purpose and whether I could change some related code safely.  I&#8217;m sure a similar story will hold for a lot of the fields in this class.</p>
<p>Just imagine, if you were writing Assembler as a C module, would you make _thisfrag a (module-level) global variable?  Almost certainly not, you&#8217;d pass it only to the functions that need it;  actually you&#8217;d probably only pass parts of _thisfrag around.  But C++ encourages you to make everything a class, and stick everything a class ever needs in as a data field, creating lots of non-local state that complicates everything.</p>
<p>(An aside:  Assembler probably also isn&#8217;t a very good basis for a class because it&#8217;s a *process*.  I figure that if you&#8217;d write something as a struct in C, then it makes for a good class in C++.  But I need to think about that some more.)</p>
<h3>Non-local state beyond classes</h3>
<p>But it gets even worse.  Good C++ practice encourages everyone to create private fields and use public get/set methods to access class data fields from outside the class.  But get/set methods are just lipstick on a pig; all too often you end up with something like this example, again from the Assembler class:</p>
<pre>    private:
        AssmError   _err;

    public:
        void        setError(AssmError e) { _err = e; }
        AssmError   error() { return _err; }</pre>
<p>Oh great, I feel much safer now.</p>
<p>It would be better to just make _err public and avoid the get/set obfuscation;  at least then it would be obvious how exposed _err is.  It also saves you from having to check the definitions of error() and setError().</p>
<p>Even better, in this case _err gets set from various places within class Assembler, but also from various places outside class Assembler.  I&#8217;ve tried twice to simplify this, by passing error codes around explicitly instead of implicitly through this quasi-global variable, but both times I was defeated by the complexity of the control flow governing how _err is accessed, in particular the fact that&#8217;s it&#8217;s set on some control paths but not others.  This is a big part of the reason why out-of-memory handling in Nanojit is a total nightmare.</p>
<h3>The end result</h3>
<p>Currently Nanojit has a number of large, complex classes, and many of them link to other large complex classes.  At many points in the code there is a bewildering amount of accessible non-local state.  (And I haven&#8217;t even mentioned how this can complicate memory management, if you end up with multiple pointers to objects.)  The complexity caused by this is a tax on development that we are all paying daily.</p>
<h3>A better way</h3>
<p>Before joining Mozilla, I spent three years programming in a functional language called <a href="http://www.cs.mu.oz.au/research/mercury/">Mercury</a>.  Mercury entirely lacks global variables (except for some very restricted cases which are rarely used).  This means that you have to pass more data around as arguments than you do in C++.  But it also means that when you look at a function, you know exactly what its inputs and outputs are, and so you can use purely local reasoning to understand what it does.  This is an *enormous* help, and one that&#8217;s easy to underestimate if you haven&#8217;t experienced it.</p>
<p>Obviously we&#8217;re not going to rewrite Firefox in a functional language any time soon.  And of course non-local state is necessary sometimes. But even C is better than C++ in this respect, because at least in C global variables are obvious and everyone knows that you should minimise their use &#8212; the language doesn&#8217;t actively encourage you to put non-local state everywhere and let you feel good about it.  Information hiding is one of the fundamental principles of programming, and object-oriented programming is meant to promote it, but unless you are very disciplined it tends to do the opposite.</p>
<p>So next time you are thinking about adding a field to a class, ask yourself: is it really necessary?  Could it be passed in as an argument instead, or something else?  Can you make your life easier by avoiding some non-local state?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/nnethercote/2009/06/19/what-i-currently-hate-most-about-c/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Valgrind + Mac OS X update (June 17, 2009)</title>
		<link>http://blog.mozilla.com/nnethercote/2009/06/17/valgrind-mac-os-x-update-june-17-2009/</link>
		<comments>http://blog.mozilla.com/nnethercote/2009/06/17/valgrind-mac-os-x-update-june-17-2009/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 01:35:04 +0000</pubDate>
		<dc:creator>Nicholas Nethercote</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Valgrind]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/nnethercote/?p=124</guid>
		<description><![CDATA[It’s time for the June update on the progress of the Mac OS X port of Valgrind.
Progress has been good:  the DARWIN branch has been merged to the trunk.  With that having happened, we&#8217;re now in sight of an actual release (3.5.0) containing Mac OS X support.  There&#8217;s some polishing and bug-fixing &#8212; both [...]]]></description>
			<content:encoded><![CDATA[<p>It’s time for the June update on the progress of the Mac OS X port of Valgrind.</p>
<p>Progress has been good:  the DARWIN branch has been <a href="http://blog.mozilla.com/nnethercote/2009/05/28/mac-os-x-now-supported-on-the-valgrind-trunk/">merged</a> to the trunk.  With that having happened, we&#8217;re now in sight of an actual release (3.5.0) containing Mac OS X support.  There&#8217;s some polishing and bug-fixing &#8212; both for Mac OS X and in general &#8212; to be done before that happens, but hopefully we&#8217;ll release 3.5.0 in early August.  That will be before Snow Leopard comes out;  another release may be necessary afterwards, but we want to get this code released sooner rather than later.</p>
<p>One interesting problem we encountered was <a href="https://bugs.kde.org/show_bug.cgi?id=193917">some users were having Valgrind abort with a SIGTRAP extremely early</a>.  It was very mysterious, and none of the developers were able to reproduce it.  Turns out that a program called Instant Hijack by a company called <a href="http://www.rogueamoeba.com/">Rogue Amoeba</a> was the cause of the problem.  Both Valgrind and Instant Hijack do some stuff with dyld, and apparently Instant Hijack&#8217;s stuff is a bit dodgy.  Turns out there&#8217;s an <a href="https://bugs.kde.org/show_bug.cgi?id=193917#c34">easy workaround</a>, which involves temporarily disabling Instant Hijack.  This was reported by a Rogue Amoeba developer, fortunately he tried Valgrind himself, had the same SIGTRAP abort, found the bug report, and realised what the problem was.  If it wasn&#8217;t for him, we&#8217;d still be scratching our heads!</p>
<p>In the meantime, keep reporting any problems you have, in particular any unimplemented syscall wrappers &#8212; a number have been added lately but there are still more to be done.  Please report problems <a href="http://www.valgrind.org/support/bug_reports.html">via Bugzilla</a> rather than in comments on this blog, as bugzilla reports are more likely to be acted upon.  Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/nnethercote/2009/06/17/valgrind-mac-os-x-update-june-17-2009/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Valgrind on Windows?</title>
		<link>http://blog.mozilla.com/nnethercote/2009/05/29/valgrind-on-windows/</link>
		<comments>http://blog.mozilla.com/nnethercote/2009/05/29/valgrind-on-windows/#comments</comments>
		<pubDate>Fri, 29 May 2009 00:16:27 +0000</pubDate>
		<dc:creator>Nicholas Nethercote</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/nnethercote/?p=117</guid>
		<description><![CDATA[With the Valgrind-on-Mac support coming along nicely, it&#8217;s worth addressing another widely-used platform:  Windows.  Will Valgrind work on Windows any time soon?  There are actually two answers:  (a) hell no, and (b) it already does (sort of).
The patch I merged from the Darwin branch onto the trunk yesterday was 28,300 lines.  And that was almost [...]]]></description>
			<content:encoded><![CDATA[<p>With the Valgrind-on-Mac support <a href="http://blog.mozilla.com/nnethercote/2009/05/28/mac-os-x-now-supported-on-the-valgrind-trunk/">coming along nicely</a>, it&#8217;s worth addressing another widely-used platform:  Windows.  Will Valgrind work on Windows any time soon?  There are actually two answers:  (a) hell no, and (b) it already does (sort of).</p>
<p>The patch I merged from the Darwin branch onto the trunk yesterday was 28,300 lines.  And that was almost entirely new code, because I&#8217;d done a lot of work to synchronize the branch and trunk so that all non-addition changes had been dealt with.  Greg Parker spent over four years, off and on, working on the original port, and I spent close to three months full time cleaning it up, and Julian Seward also pitched in a bit.  I roughly estimate the Darwin port represents at least 1,000 person-hours of work, possibly much more.</p>
<p>And Mac OS X is a <strong>lot</strong> closer to Linux than Windows is.  Also, the Mac OS X kernel is open source, which makes a port much easier.  A Valgrind-on-Windows port would therefore be an enormous undertaking, one that is unlikely to happen soon, if ever.  That is how we get answer (a) above.</p>
<p>However, although Valgrind doesn&#8217;t run on Windows, it is possible to run Windows programs under Valgrind, thanks to <a href="http://www.winehq.org/">Wine</a> &#8212; you run the Windows program under Wine, and Wine under Valgrind.  The development (trunk) versions of both Valgrind and Wine now have enough awareness of each other that they can apparently be used together.  I say &#8220;apparently&#8221; because I haven&#8217;t tried it myself, but I know that others have had some success.  But please note that this is fairly new and experimental, and should only be tried by those not afraid to get their hands dirty (<a href="http://wiki.winehq.org/Wine_and_Valgrind">this page</a> has more details). And that&#8217;s how we get the answer (b) above.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/nnethercote/2009/05/29/valgrind-on-windows/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mac OS X now supported on the Valgrind trunk</title>
		<link>http://blog.mozilla.com/nnethercote/2009/05/28/mac-os-x-now-supported-on-the-valgrind-trunk/</link>
		<comments>http://blog.mozilla.com/nnethercote/2009/05/28/mac-os-x-now-supported-on-the-valgrind-trunk/#comments</comments>
		<pubDate>Thu, 28 May 2009 03:31:04 +0000</pubDate>
		<dc:creator>Nicholas Nethercote</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Valgrind]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/nnethercote/?p=111</guid>
		<description><![CDATA[This morning I merged the DARWIN branch, which had been holding Valgrind&#8217;s support for Mac OS X, onto the trunk.  The branch is now defunct, and Valgrind-on-Mac users should check out the trunk like so:
svn co svn://svn.valgrind.org/valgrind/trunk &#60;dirname&#62;
cd &#60;dirname&#62;
and then build it according to the instructions in the README file.
This is a good thing, [...]]]></description>
			<content:encoded><![CDATA[<p>This morning I merged the DARWIN branch, which had been holding Valgrind&#8217;s support for Mac OS X, onto the trunk.  The branch is now defunct, and Valgrind-on-Mac users should check out the trunk like so:</p>
<pre>svn co svn://svn.valgrind.org/valgrind/trunk &lt;dirname&gt;
cd &lt;dirname&gt;</pre>
<p>and then build it according to the instructions in the README file.</p>
<p>This is a good thing, if only because it means I can spend less time maintaining a branch and more time actually fixing things.</p>
<p><strong>Update:</strong> fixed the svn URL.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/nnethercote/2009/05/28/mac-os-x-now-supported-on-the-valgrind-trunk/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>
