Over the past three weeks or so, Jeff Muizelaar and I started to investigate what it would take for us to be able to use clang-cl to build Firefox on Windows, and I’m really excited to report that as of…
Over the past three weeks or so, Jeff Muizelaar and I started to investigate what it would take for us to be able to use clang-cl to build Firefox on Windows, and I’m really excited to report that as of…
One of the most often requested features in the private browsing support for Firefox has been the ability to open a private window without needing to close the entire session. Over the past 19 months, we have been working on…
Firefox 15 is released on August 28th. Among many new features implemented in this release is background updates. This feature allows Firefox to download the update in the background, apply it alongside with the existing installation, and keep the updated version around so that it can quickly switch to it the next time that the browser starts up. This effectively eliminates the update progress dialog that appears when you start Firefox after it has downloaded an update:
I previously wrote about this project. You can see that post for more technical details. This feature landed a while ago on the Nightly channel, and we soon discovered a few issues which we addressed in time for this to get uplifted and enabled on the Aurora channel. Luckily no new issues were discovered with this feature as it rode the train to get on the Beta channel, and will get in the hands of all of Firefox users on Windows, Mac and Linux as part of the Firefox 15 release.
This was one of the scariest projects that I’ve ever worked on, since messing something up in the updater component could have catastrophic consequences in case it prevents users from being able to update to newer Firefox revisions. I’m happy that the results of this project will soon get in the hands of millions of Firefox users, and I would like to thank Robert Strong, Brian Bondy, and the wonderful members of our Release Engineering (in particular, Ben Hearsum and Chris AtLee) and QA teams (in particular, Vlad Ghetiu) who helped me a lot along the way. You guys rock, for being extremely helpful, and for making this large project possible!
The dialog below should look familiar. It displays while Firefox completes the update process after a new version is installed and the browser is restarted.
In order to update itself, Firefox first starts to download an update in the background. When the update is downloaded, Firefox stages it in a directory ready to be applied. The next time that Firefox is about to start up, it checks out the staging directory. If an update ready to be applied is found, Firefox launches the updater program, and applies the update on top of the existing installation (showing that progress bar as it’s doing its job). When the update process is finished, the updater program restarts Firefox. All of this happens as you’re waiting for your browser to start up in order to do what you wanted to do. This is clearly less than ideal.
For the past few weeks, I have been working on a project to improve this process. The goal of my project is to minimize the amount of time it takes for Firefox to launch after downloading an update. The technical details of how I’m fixing this problem can be found this document. Here’s a short version of how the fix works. When Firefox finishes downloading an update, it launches the updater application in the background without displaying any UI, and applies the update in a new directory that is completely separate from the existing installation directory. Instead of staging the update itself, an entire updated version of Firefox is staged. The next time that Firefox starts up, the existing installation is swapped with the new updated installation which is ready to be used. In this scenario, you likely won’t notice that Firefox has applied an update as no UI is shown.
Now, the reason that this approach fixes the problem is that swapping the directories, unlike the actual process of applying the update, is really fast. We are effectively moving the cost of applying the update to right after the update has been downloaded while the browser is running. This leaves only the really fast copy operation to be performed the next time that the browser starts up.
I have some experimental builds with this feature ready in a temporary channel called Ash. The implementation is now at a stage where it can benefit testing from the community. You can download the latest builds here. I will trigger a few nightly builds on this branch every day so that you would get updates if you’re running an Ash build.
In order to help with testing this new update process, all you need to do is to download the latest build from Ash, then wait a few hours so that a new nightly build becomes available, and then update to that build. Updating can be triggered manually by opening the About dialog, or by the background update checker if you leave the build running for a few hours. If everything works correctly, when you restart Firefox, you should get a new build without seeing any progress bar as Firefox is starting up. In order to verify that you have indeed been updated to a new build, you can go to about:buildconfig, copy its contents, and then compare it with the contents of about:buildconfig when Firefox starts up after an update.
It would be extremely useful if you can test this with different types of security and anti-virus software running. If you observe any problems or warning, or if you see that the update did not change the contents of about:buildconfig, then please let me know so that I can try to fix those problems.
Please note that this is still in the testing stage, and at this point, we’re not quite sure which version of Firefox this will land in (we’re working to land it as soon as is safely possible). No matter which version of Firefox includes this feature for the first time, we believe that this will be a very positive change in making the Firefox update experience more streamlined for all of our users.
Address Sanitizer is a new project based on clang which aims to provide relatively cheap memory access checking. It is capable of detecting errors such as out-of-bounds access or use-after-free at runtime. Although its functionality is a subset of what Valgrind supports, running applications built with Address Sanitizer is noticeably faster than running them under Valgrind, which can simplify the testing process.
I recently got a build of Firefox with Address Sanitizer working. Getting these builds in relatively simple. Firstly, you should build Address Sanizer yourself. Then, you can use a mozconfig like this:
export CC=/path/to/address-sanitizer/asan_clang_Linux/bin/clang export CXX=/path/to/address-sanitizer/asan_clang_Linux/bin/clang++ export CFLAGS='-fasan -Dxmalloc=myxmalloc' export CXXFLAGS='-fasan -Dxmalloc=myxmalloc' export LDFLAGS=-ldl . $topsrcdir/browser/config/mozconfig mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-ff-asan mk_add_options MOZ_MAKE_FLAGS="-j4" ac_add_options --enable-application=browser ac_add_options --enable-debug ac_add_options --disable-optimize ac_add_options --disable-jemalloc ac_add_options --disable-crashreporter
Once your mozconfig is set up, just build and run Firefox as you normally would. I have not yet found any memory safety issues in Firefox using Address Sanitizer, but it’s not really surprising, since I mostly attempted to run our unit tests with this build, but the build is fast enough that you can even use it as your main browser. If you do see an issue, please file a bug.
When debugging a test, I’ve sometimes found it useful to have access to an extension such as DOM Inspector or Firebug to debug what’s going on with the test. In the past, you could do this by a bunch of hacks to make sure that you get the extension inside the test profile folder in time so that the test harness doesn’t delete it for you. But last week I landed a patch which enables you to do this more efficiently. Here’s how the new setup works:
For example, if you want to have Firebug when running the mochitest suite, here’s how you should start the suite:
python objdir/_tests/testing/mochitest/runtests.py --install-extension=firebug\@software.joehewitt.com.xpi
Update: We had to pull these changes out of Firefox 4 because of some regressions that they caused. We will revisit this issue after Firefox 4, and will hopefully deliver this set of fixes in the next version of Firefox.
I landed a patch today which changes the Firefox 4 built-in spell checker in two important ways:
Here is the slightly longer version of what changed. Before this change, when Firefox saw a word such as "scot-free", it would break it into two words, "scot" and "free", and pass each of them to Hunspell (which is the spell checking engine we use) to see if they are correctly spelled or not. So, even though the word was correctly spelled, Hunspell would not have any way to know that, because all it saw was Firefox asking it whether "scot" is correctly spelled, and whether "free" is correctly spelled. The result was that "scot" was underlined as incorrectly spelled.
After this change, Firefox would pass the entire word, "scot-free" to Hunspell, which would enable Hunspell to recognize the whole word, and make the correct decision about its spelling. This is especially important for the languages which use the hyphen character as part of the non-compound words frequently.
Also, previously, Firefox would automatically mark any word with more than 64 letters as being incorrectly spelled. This is a problem for languages which tend to have words much longer than that, such as German and Swedish, to name a few. The new limit is 130 letters. This new limit might also not be enough for some words in some languages. We plan to remove this limit entirely in future Firefox versions.
If you’re a localizer, or a dictionary author, there shouldn’t be any need for you to change the dictionary files for your language. However, it would be great if you can test Firefox 4 nightlies starting from tomorrow with your languages to verify that it correctly recognizes long words in your language, or those words which have a hyphen in them (and are not compound words). Keep in mind that these changes will only affect your language if the dictionary is capable of recognizing those words. If you see any issues with this, please file a bug to let us know.
For the gory details, the curious reader can read bug 355178.
Recently, I decided to convert my Bugzilla Tweaks jetpack to an extension based on the Jetpack SDK, which is still under development. This post is meant to be a document of my experience with the Jetpack SDK for creating a real-world and useful extension for Firefox.
As the very first step, I needed to actually get the SDK set up and running. So, I went straight to the Getting Started guide. Here is how I set it up. I cloned the hg repository (to make sure that the process of updaring my extension to future versions of the Jetpack SDK is as easy as just updating the repo and rebuilding the extension). At this point, you can make a choice. You may either want to stay on tip, or update to a release version (which may be a little more stable than tip — but remember that the Jetpack SDK is still under development). I chose to update to 0.4, which is the latest released version as of this writing.
Then, I went ahead with . bin/activate and cfx testall, to make sure that I’ve get a working environment up and running. I sat there and watched the command prompt waiting for the tests to be completed, but I got tired and pressed Ctrl+C to cancel the operation after about 5 minutes. Then, I decided to run cfx testall –verbose to see what’s happening, but again, it just went yoohoo after running some tests. I canceled again and decided to just assume that everything is working correctly, for lack of a better way to actually verify that.
Then I proceeded to read the Packages documentation. I skimmed over it, and then proceeded to the Programs documentation. That seemed to be interesting, so I read that more thoroughly. It all seemed easy enough. The only strange part was that I seemed to have to create my packages under the Jetpack SDK directory. That seems less than ideal to me, but I decided to try to create a real directory for my extension somewhere, and just add a symlink to it under the packages directory. That worked, which was nice.
After this point, I just copied the old bugzilla-tweaks.js file as lib/main.js, and started to figure out how to make the extension do something useful. Before anything else, I’d need something equivalent to the Jetpack Prototype’s pageMods facility. So, I grabbed Atul’s persistent-page-mods.js module, and started looking at it (he’d pointed me to it here). Soon I figured out that I needed to have the dependencies of this package available as well. I searched for "require" in that file, and found out that it depends on timer, errors and unload-2. The only one not available in jetpack-core was the latter, so I grabbed it as well. unload-2 itself didn’t have any dependencies besides unload, which ships in jetpack-core, so the dependency search was done. One thing that I wish we had was a tool to recursively extract the dependencies from any given package. Atul also told me that I needed the tab-browser package, but I noticed that it’s there in 0.4.
Then I stole this code to get the pageMods functionality hooked up. This far into the process, I’m loving how easy it is to use other people’s packages and code in your new Jetpacks. I think that’s going to blow away how people write extensions for Firefox and other Mozilla-based applications.
For the most part, the Bugzilla Tweaks jetpack is a bunch of DOM API calls, and I expected those parts to just work. I only needed to port my Jetpack Prototype API usage over to Jetpack SDK APIs. In addition to pageMods, I used jetpack.menu to add context menu items, and jetpack.clipboard to modify the clipboard.
The context-menu API documentation was straightforward, and I ported my usage of the jetpack.menu API to context-menu very quickly. Porting jetpack.clipboard was a bit more involved, though, because jetpack-core does not include a clipboard module yet, so I had to write my own.
I decided to go with the JEP specification of the clipboard API, which has not been implemented yet. This is a relatively simple API, providing three methods: get, set and getCurrentFlavors. For this extension, I only needed the set method, so that’s what I implemented for now.
I also had two direct XPCOM call sites in my original Jetpack, one for reading a preference, and the other for reading a cookie. Jetpack SDK comes with a preferences-service package, so I decided to use it. I also created a small cookiemanager package and switched to using it. The benefit of this is that if in the future, the Jetpack SDK does not allow direct usage of XPCOM components, I can just modify one package. Also, I can use the package in my other projects, and so can others!
Now was the time to try the extension for the first time! Before generating the XPI, I added a few more fields to the package.json manifest, and then I ran cfx xpi. It told me that I needed to remove the id field from the manifest, which I did. The next time I ran cfx xpi, it told me that the manifest is updated, and I need to run the cfx xpi again. This was kind of strange, and less than ideal (why didn’t the tool do what’s needed on its own?). Anyway, I re-ran cfx xpi, and finally I had an XPI, waiting to be tested.
But before testing, I was curious to see for myself what the generated XPI contains. So, I unzipped the package, and started looking around. The generated install.rdf contained entries for Firefox, Fennec and Thunderbird. I found that strange. I was never asked which applications this extension is compatible with. I’m pretty sure that it won’t be compatible with Thunderbird, and I don’t even know what will happen if I try to install the XPI on Fennec. And if the goal is for the extension to be compatible on all Mozilla-based applications, it should be a toolkit extension, right?
I also noticed that the install.rdf contains a bootstrap element, which means that the extension can be installed without Firefox being restarted if you use a trunk version. Nifty!
Then, there was the resources directory, which contained a copy of all the Jetpack packages, both in bugzillatweaks, and in jetpack-core. What I found really broken was that .main.js.swp, which is the Vim swap file which was around because I had main.js open in Vim made its way to the XPI package. Not so nice.
There was also a components directory, containing a harness.js file, which I didn’t look at very carefully.
So, I went ahead and opened up a development profile that I had set up to develop and test the old version of the jetpack in Firefox 3.6. I disabled the original jetpack, dropped the XPI into Firefox, and restarted. Lo, and behold! I had my extension installed, but it didn’t work! There was no error logged to the error console, and no possible way to tell what was going wrong. I felt clueless as how to proceed. I decided that having Jetpack Prototype installed might be conflicting with something, so I disabled that extension and restarted. Still no luck.
So, I went ahead and added a bunch of console.log calls in the beginning of the main function, to see if it’s called, but apparently it wasn’t. I decided to give things a shot with a nightly. So, I launched a nightly Firefox from the console, and boy was I lucky to have done that! I got this error on the console (that is, the OS X Terminal application):
error: An exception occurred. Traceback (most recent call last): File "resource://jid0-qbniplfdfa4lpdrjhac6vbqn20q-bugzillatweaks-lib/main.js", line 340, in null }); SyntaxError: syntax error
OK, that explains a lot. But I found this out completely out of luck. The SDK really needs to expose such errors in a more discoverable way.
So, I went ahead and fixed the syntax error, re-generated the XPI, and opened it in Firefox. Because it’s a rebootless add-on, it didn’t require the browser to restart, and I got "info: main" on the console (again, the OS X Terminal application), which was the debugging message I had added to my main function, so the jetpack was correctly loaded!
But apparently I have to watch the Terminal window instead of Firefox’s error console, which sucks.
From there on, I spent some time debugging using console.log calls, and finally I managed to have a working Jetpack.
The entire process was rather pleasant. I hit a few bumps along the road, as I explained above, but hopefully others will read this post and know how to avoid them while the amazing guys in the Jetpack SDK team fix those issues.
One of the things that we at Mozilla would like to do better at is the amount of time it takes between when you launch Firefox, and when it starts up and is usable. We’ve been tackling this problem for quite a while, and have already made tremendous improvements. But we think we can still do better.
Last week, Vlad landed the function timer API, which can be used for producing a log of how much time it takes to execute any given code block. This is a very useful framework for measuring how much time different things consume at Firefox startup. On Monday, I, Vlad, Shawn, Johnathan, and Shaver started to look into instrumenting Firefox to produce a useful log of what goes on at Firefox startup, to be able to analyze it to identify the areas that we’re being slow at, in order to focus our attention to improve those pieces of code.
I set up a clone of mozilla-central here to so that we can focus on adding probes to the code without being slowed down by trying to lands things on mozilla-central for now. Then, we started to add probes like crazy. The probing work is really finished now, and I think that we’ll spend some time tomorrow to try to analyze the logs, in order to be able to make some sense out of them, and identify the areas where we can attack in order to get the most gain in reducing the startup time.
If you want to create your own startup logs, here are the steps to do that. Please note that these instructions are for Windows. Other platforms can be measured similarly, but we’re trying to focus our attention to Windows for now.
Here is a bit of information about the format of the log. On each line, you will see a pattern like this:
[ 123.45] > ( 5) |nsContentDLF::CreateBlankDocument (line 349)
[ 244.43] * ( 2) | 0.50 ms ( 0.65 ms total) – NS_InitXPCOM3_P (line 480) [Next: timer startup]
[ 330.21] < ( 10) | 3.48 ms ( 3.48 ms total) – mozJSComponentLoader::Import (line 1444) (file: resource://gre/modules/XPCOMUtils.js)
Here is what each of these items mean:
Johnath has also adapted a script to generate graphs from the logs, but at this point, we’re thinking that the graphs are misleading, and therefore I’m not going to talk more about this, but check the bug for more information (including how to create such graphs, and some graph samples.)
The next steps probably include finding out where there are gaps in our logs, and try to add probes to cover those areas. We also need to generate logs for a range of different profiles, including blank and heavy ones. We need to generate a variety of logs to ensure that we’re not missing any obvious use case of Firefox. We are also trying to figure out which types of visualizations for this data would be helpful, to be able to better filter/present the generated logs. Hopefully, we’ll soon have a number of actionable tasks which we can pursue to reduce Firefox startup time to a significant degree.
If you have any ideas how to improve things, or have any logs which we need to see, either comment here or in the bug.
Atul Varma has built an user name autocomplete tool for Bugzilla. This reminded me that it’s been a long time since I wanted to add this functionality to the Bugzilla Tweaks jetpack. Last week I added this feature, but I didn’t get the time to blog about it!
Here is how it looks on a a sample bug:
It is also smart enough to handle multiple users for fields which accept it.
It works on almost everywhere in Bugzilla where you can enter a user name. Here is the full list for the curious:
This is providing the same functionality of Atul’s tool, with two added benefits: it provides the functionality right where you need it, and doesn’t require you to enter your user name and password.
No more memorizing people’s email addresses! No more asking around for their email addresses! No more bugzilla error pages telling you that the user name you entered doesn’t exist, or couldn’t be matched exactly! I hope you like the idea.
The jetpack lives here. If you have already installed it, you can either rely on Jetpack Prototype’s auto-update feature, or refresh it manually.