Here in CDOT at Seneca College, we regularly push the boundaries of what is capable in browsers with projects like Processing.js and Popcorn.js. But sometimes we break those boundaries and we find neat bugs in browsers. Rather than sitting around and complaining, David Humphrey encourages the following steps be taken to fix a bug:
- Create a test
- File it
- Fix it
I consider myself a good developer, but filing and fixing my first few Firefox bugs was intimidating. I’m documenting the process here to show that it’s possible for someone with a small understanding of how Mozilla’s development process works can contribute.
Bug 679977 – TM: Variable assignment fails, gets assigned undefined
The first bug that I filed was found in the Processing.js reference tests. The reference tests compare an image that we consider correct, to the live Processing sketch, which is compared visually to look for errors. Every so often, some of our ref tests would fail like this:

It was maddening to track down though. It would only occur in Firefox, and any attempt to debug the problem made it go away. Clearly the ref test environment was important in triggering the bug. The key to finding this bug lied in the error message from the first ref test: “cachedVertArray is undefined”. I looked at the associated lines of code and what I saw made absolutely no sense at all:
var cachedVertArray;
// Loop through the list of vertices
for (i = 0; i < vertArrayLength; i++) {
// Copy a single vertice to our variable
cachedVertArray = vertArray[i]; /* This gets assigned undefined */
if (!cachedVertArray) { // Check to see if the assignment worked
// If we assign it again, it works fine!
cachedVertArray = vertArray[i];
For some reason, the JavaScript engine in Firefox was not assigning values correctly. That’s bad. But I had a reproducible test case now; that’s good. With my test case in hand, I visited the #jsapi channel on irc.mozilla.org, which is where are the JavaScript engine hackers lived. I linked to my live test case, and asked for some help in filing the bug properly. One of the users, sstangl, confirmed that it was a JavaScript JIT bug:
sstangl: jbuck: it’s a JIT bug in JaegerMonkey. If you turn off ‘javascript.options.methodjit.content’ in about:config, it passes.
The JIT (just-in-time) compiler is the magic that makes JavaScript so fast these days. However, it was mis-optimizing some code, which was causing the bug in the Processing.js ref tests.
So I had a test case, and a bug filed. At this point, others jumped in and reduced the test case down to a manageable 20 lines. shu contributed the patch that fixed the bug for us, which was also his first JavaScript tracer bug. And now that Firefox 9 is out, we can edit our list of known ref test failures. And all I had to do was get a good test case, and file a bug with Mozilla.
Bug 679977 – Add an XInput backend for Windows gamepad support
One of the things we’re working on adding to Firefox is Gamepad support (Bug 604039). For each operating system, we need to add a backend to communicate with platform-specific gamepad APIs. On Windows this is DirectInput, on Linux it’s SDL, and on Mac OS X it’s IOHIDManager. On Windows, there’s a second gamepad API called XInput. XInput is for Xbox 360 controllers, while DirectInput is for any controller. Although it might seem like a waste of time to implement dual backends for Windows, XInput makes the Xbox 360 controller work much better than it would with DirectInput. I’ve worked with XInput before, so I requested that I get assigned to the bug.
Step 1 – Build Firefox
The first step in working on any Firefox bug is getting a local build compiling. I’ve done before on on Mac OS X and Linux, but doing the same thing on Windows was simply not working for me. My console would just randomly hang, with no discernible reason. After a few hours of banging my head against the build system, I asked for help in the #developers channel, where nearly all of the Mozilla developers hang out. khuey was easily able to diagnose the problem after looking at my .mozconfig file:
mk_add_options MOZ_MAKE_FLAGS="-s -j8"
ac_add_options --enable-debug
ac_add_options --disable-optimize
The problem was my use of -j8 on Windows with GNU make. On any other platform, it’ll allow compiles to work in parallel, and offer a significant speed boost. On Windows, it randomly deadlocks! The solution was to use pymake, a GNU make replacement written entirely in Python. I was able to continue working on my XInput patch, which is currently hibernating on Github, but I was bothered by the fact that I wasted hours on a simple problem that could’ve been solved with an error message in my console.
Step 3 – Find something to work on
A good starter bug in Firefox is fixing your pet peeve. In my case, I wanted to print out an error message when building Firefox on Windows when -jN is passed to GNU make. Fixing the Firefox build system can’t be too hard, right?

This guy showed up when I said that
Bug 705479 – Parallel builds (-jN) on Windows should fail early if gmake is being used (aka Steps 4, 5, 6, and 7)
Before I assigned myself to the bug, I decided to try and bang out a quick patch. After all, this was my first Firefox patch and I wasn’t too sure I could do it yet. I decided to start my patch with the main Makefile that is used for all top-level builds, client.mk. This is not ideal for two reasons pointed out in review:
- Applies to all Mozilla projects, with no way for other Mozilla projects to opt-out
- Developers doing a build inside the object directory would not get the error message
khuey recommended moving the Makefile check to browser/build.mk which is only executed when building Firefox, and run whether doing a top-level or object directory build. ted also mentioned on IRC that GNU make would only deadlock when using multiple CPUs, so it’d be important to check the NUMBER_OF_PROCESSORS environment variable is greater than 1. With this feedback, I came up with patch attempt #2. I was getting closer, but my patch would break builds for people with multiple CPUs who did not pass -jN to make.
At this point I was at an impasse. I needed to check the MAKEFLAGS variable, but make is odd in that it actually does two passes over a file. First, it reads in the entire file, executing lines that are not within a target. Next it expands all variables in the second pass, when it executes a target. This means that the MAKEFLAGS check must be within a target. Google helped me to find a way to do this, but I was still stuck with the problem of putting it in a target that would always get executed. While browsing the various Makefile.in’s, I found this curious line in the root Makefile.in:
default::
What the heck does default:: mean? After a bit of searching I found the Make manual section on Double-Colon Rules which says:
When a target appears in multiple rules, all the rules must be the same type: all ordinary, or all double-colon. If they are double-colon, each of them is independent of the others. Each double-colon rule’s recipe is executed if the target is older than any prerequisites of that rule. If there are no prerequisites for that rule, its recipe is always executed (even if the target already exists). This can result in executing none, any, or all of the double-colon rules.
This is exactly what I needed! Due to the structure of the Mozilla build system, the default:: target will always be executed in any Makefile. With my MAKEFLAGS problem solved, I whipped up a third patch which passed review and got landed by khuey in mozilla-central on November 30th.
Step 8 – Repeat
Now that I got my first bug landed, I wanted to do another. Before doing that I took the recommended step of requesting level 1 access. Level 1 access means that I can push patches to the try servers, which can build and test my patches on more platforms than you can shake a stick at. The process to get the different levels of access is spelled out on the Becoming A Mozilla Committer page.
Bug 691876 – Cannot run Windows jsshell nightlies: mozutil.dll missing
Back in the summer, David added a standalone js shell to the Firefox nightly builds (Bug 543463). We use it in Processing.js for unit and parser tests, and it’s nice to have a downloadable binary, rather than building from source. A change in the memory allocator for the js shell broke the binary that shipped in the Nightly build; it required mozutils.dll/.so, but the packager did not zip that up with the binary. Looking at the patches that David wrote, it was pretty easy to figure out what I needed to add. And I got to use my newfangled try server privileges which was neat.
Because only level 3 developers can commit code to mozilla-central, once a patch has passed review, the assignee (myself, in this case) is required to add ‘checkin-needed’ to the Whiteboard. This indicates to whoever is on build duty that they should push the patch to mozilla-inbound, where it gets built and tested before being pushed to mozilla-central.
The patch I’m working on currently is adding CORS support to cross-origin <video> elements (Bug 682299). I’m nearly done it, and I promise to write up a timely blog post when I finish it
You can contribute too
As developers, we can do better than just waiting for someone else to fix it. There’s plenty of help and guidance available on the Mozilla Developer Network wiki and on the #introduction chat room on irc.mozilla.org. Even if you’re not a C++ guru, there’s tons of places that Firefox could use some help in. Jump in, and contribute!