Is Firefox really that bad?

When I’ve read some rants about Firefox I thought they were a little bit too much. Now, I start to wonder if they were quite to the point instead. But before I start I have to say I haven’t tried contacting anybody yet, neither from the Gentoo Mozilla team not upstream. And I’m sure the Gentoo Mozilla team are doing their best to make sure that they can provide a working Firefox still following upstream guidelines on trademarks.

This actually sprouted from my previous work inspecting library paths; I went to check which libraries for firefox-bin were loaded from the system library directory, and noticed one curious thing: /usr/lib/ was being loaded. What’s the problem? The problem is that I knew that xulrunner (at least built from sources) bundles its own copy of SQLite3, so I wondered if they used the system copy for the binary package. Funnily enough, they really don’t:

yamato link-collisions # ldd /opt/firefox/firefox-bin | grep sqlite3 => /opt/firefox/ (0xf67e7000) => /usr/lib/ (0xf621e000)
yamato link-collisions # /opt/firefox/firefox-bin | grep sqlite3 -B1 => /opt/firefox/ => /opt/firefox/
-- => /usr/lib/nss/
   => /usr/lib/

(The script comes from pax-utils and uses scanelf. I have a similar script in my Ruby-Elf suite implemented as a testcase, it produces the same results, basically.)

So the binary version of the package uses the system copy of NSS and thus loads the system copy of SQLite3. I haven’t gone as far as checking where the symbols were resolved, but one of the two is going to be loaded and unused, wasting memory (clean and dirty, for relocated data sections). Not nice, but one can say it’s the default binary, and has to know to adapt. In truth the problem here is that upstream didn’t use rpath, and thus the firefox-bin program does not load all its libraries from the /opt/firefox directory (since the /usr/lib/nss directory comes first). Had they built their binary with rpath set to $ORIGIN it would have loaded everything from /opt/firefox without caring about the system libraries, like it was intended to do. Interestingly enough, they do just that for Solaris, but not for Linux where they prefer fiddling with LD_LIBRARY_PATH.

Next, I checked the /usr/bin/firefox started, which I already copied on the other post:

export LD_LIBRARY_PATH="/usr/lib64/mozilla-firefox"
exec "/usr/lib64/mozilla-firefox"/firefox "$@"

Let’s ignore the problem with the rewriting of the environment variable, which I don’t care about right now, and check what it does. It adds the /usr/lib64/mozilla-firefox directory to the list of paths to load libraries from. Since it’s setting LD_LIBRARY_PATH all the library resolutions will have to be done manually rather than using the file. So I checked which libraries it loads from there:

flame@yamato ~ % LD_LIBRARY_PATH=/usr/lib64/mozilla-firefox ldd /usr/lib64/mozilla-firefox/firefox | grep mozilla-firefox
flame@yamato ~ % scanelf -E ET_DYN /usr/lib64/mozilla-firefox 
ET_DYN /usr/lib64/mozilla-firefox/ 

(The second commands finds all the libraries in the given path, by checking for ET_DYN, dynamic ELF, files.)

Okay so there is one library, but it’s not in the NEEDED lines of the firefox executable. Indeed that library is a preloadable library with a different malloc() implementation (remember I’ve written about similar things and commented about FreeBSD solution), which means it has to be passed through LD_PRELOAD to be useful, and I can’t see that to be used at all. Indeed, if I check the loaded libraries on my firefox process I can’t find it:

flame@yamato x86 % fgrep jemalloc /proc/`pidof firefox`/smaps
flame@yamato x86 % 

Let’s go step by step though, for now we can say with enough safety that the loader is overwriting LD_LIBRARY_PATH with no apparent good reason. Which libraries does the firefox executable load then?

flame@yamato ~ % LD_LIBRARY_PATH=/usr/lib64/mozilla-firefox ldd /usr/lib64/mozilla-firefox/firefox =>  (0x00007fffcabfd000) => /lib/ (0x00007fa5c2647000) => /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.3/ (0x00007fa5c2338000) => /lib/ (0x00007fa5c1fc5000)
    /lib64/ (0x00007fa5c284b000) => /lib/ (0x00007fa5c1d40000) => /lib/ (0x00007fa5c1b28000)
flame@yamato ~ % scanelf -n /usr/lib64/mozilla-firefox/firefox 
ET_EXEC,, /usr/lib64/mozilla-firefox/firefox 

It can’t be right, can it? We know that Firefox loads GTK+ and a bunch of other libraries, starting with xulrunner itself, but there is no link to those. But if you know your linker you should notice a funny thing: It means the exeutable is calling into the loader at runtime, which usually means dlopen() is used. Indeed it seems like the firefox executable loads the actual browser at runtime, as you can see by checking the smaps file.

Now there are two things to say here: there is a reason why firefox would be doing that, and the reason is that calling “firefox” with it open already should actually request a new window to be opened, rather than opening a new process. So basically I expect the executable to contain a launcher, that if a copy of firefox is running already just tells that to open a new window, and otherwise loads all the libraries and stuff. It’s a good idea, from one point of view because initialising all the graphical and rendering libraries just to tell another process to open a window would be a waste of resources. On the other hand, dlopen() is not the best performing approach and also creates problem to prelink.

I have no idea why it happens, but the binary package as released by upstream provides a script that seems to be taking care of the launching, and then a firefox-bin executable that doesn’t use dlopen() to load the Gecko engine and all the graphical user interface. I would very much like to know why we don’t do the same for from-source builds, I would sincerely expect that the results would be even better when using prelink and similar.

Now, let’s return a moment to the problem of the SQLite3 loaded twice for the binary release of Firefox, surely the same wouldn’t happen for the from-source version, would it? Check it by yourself:

flame@yamato x86 % fgrep sqlite /proc/`pidof firefox`/smaps
7fea6c8c2000-7fea6c935000 r-xp 00000000 fd:08 701632                     /usr/lib64/
7fea6c935000-7fea6cb35000 ---p 00073000 fd:08 701632                     /usr/lib64/
7fea6cb35000-7fea6cb36000 r--p 00073000 fd:08 701632                     /usr/lib64/
7fea6cb36000-7fea6cb38000 rw-p 00074000 fd:08 701632                     /usr/lib64/
7fea814dc000-7fea8154f000 r-xp 00000000 fd:08 24920                      /usr/lib64/xulrunner-1.9/
7fea8154f000-7fea8174f000 ---p 00073000 fd:08 24920                      /usr/lib64/xulrunner-1.9/
7fea8174f000-7fea81751000 r--p 00073000 fd:08 24920                      /usr/lib64/xulrunner-1.9/
7fea81751000-7fea81752000 rw-p 00075000 fd:08 24920                      /usr/lib64/xulrunner-1.9/

Yes, yes it does happen. So I have a process that is loading one library for no good reason at all at runtime, and not a little one at that, when it could probably, at this point, use a single system SQLite library. I say that it could, because now I have enough evidence to support that: if the two libraries had a different ABI, depending on which one the symbols resolve to, either xulrunner or NSS would be crashing down. Since ELF uses a flat namespace, the same symbol name cannot be resolved in two different libraries, and thus one of the two libraries using them would find them in the “ẅrong” copy. And no, before you ask, neither use symbol versioning.

So at this point the question is: can both Firefox upstream and the Gentoo Firefox ebuild start providing something that does more than just working and actually works properly?

20 thoughts on “Is Firefox really that bad?

  1. Apart from the fact that firefox’ codebase is a piece of crap, their organisation is crap too: they have no clear goals _at all_. I’m waiting for chrome to hit linux, since it seems to be one of the only browsers which appears to have at least some kind of goal statements.


  2. @tulcod: chrome is no better than firefox on resources. besides it has a nasty eula ;)@diego: it would be nice to forward your post to firefox upstream!


  3. I don’t think it’s an upstream problem, there’s

      mozconfig_annotate '' --enable-system-sqlite

    in xulrunner ebuild, but it’s commented out. Just ask Gentoo Mozilla team why they did it. I uncommented it and Firefox still works.


  4. @tulcod – why is it crap? I’ve got what is by today’s standards an “average” PC and I’ve never had any issues with it, operationally or resource-wise.


  5. @everyone who claims firefox isn’t crap because it runs OK: just the fact that it runs without many problems doesn’t mean the code is clean. And imo, it has some problems. For example, it stutters mouse-based scrolling when it’s doing… something, while it doesn’t stutter if you just drag the bars. It’s not really a critical problem, but imo it indicates that something is wrong with the codebase. Oh, and before you guys argue that I’m just basing my opinions on such things, don’t worry: I’ve read (a bit of) the code.Firefox is a piece of crap, but unfortunately it’s the best piece of crap out there.


  6. I actually have to agree with tulcode here, Firefox _is_ bad when it comes to the actual code, just like this post shows for what concern linking methods. I also agree there isn’t much better to use, nowadays. I tried most of the other stuff, but I really feel the need for some Firefox extensions like delicious integration and AdBlock.But I don’t have my hopes up with Chrome sincerely, because a) I don’t trust Google that much and b) I don’t think they would ever implement an AdBlock extension because, well, it would hinder them with their AdSense (yes I know it’s a bit strange to read me saying this when this very site has AdSense…)/As for what forwarding upstream, I posted this hoping that the Gentoo Mozilla team could pick this up before going upstream because I wouldn’t know how to approach them regarding this. The SQLite thing, by the way, might actually produce a FF build that cannot be legally called FireFox, thus why it might be commented.


  7. AFAIK the current mozilla-firefox ebuild doesn’t use system sqlite because upstream found a number of miscellanous problems (performance regressions, a couple of serious bugs, etc.) with the sqlite releases following the one included in firefox. IIRC, mozilla tried to upgrade their bundled copy a few times but they were always forced to revert.I am forcing system sqlite on my machine, and I never had any problem, but of course I don’t run hundreds of automatic tests so I could’ve simply missed the regressions.


  8. I just thought I’d say the situation has changed a little under the new 3.1 alphas, at least my install is a bit different.Hope you find them helpful, or at least, interesting. $ file /usr/lib64/xulrunner-1.9/ /usr/lib64/xulrunner-1.9/ cannot open `/usr/lib64/xulrunner-1.9/‘ (No such file or directory)– $ scanelf -E ET_DYN /usr/lib64/mozilla-firefox $– $ fgrep jemalloc /proc/`pidof firefox`/smaps $–

      LD_LIBRARY_PATH=/usr/lib64/mozilla-firefox ldd /usr/lib64/mozilla-firefox/firefox =>  (0x00007fff6ddfe000) => /lib/ (0x0000003f78e00000) => /lib/ (0x0000003f78a00000) => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.0-alpha20090123/ (0x0000003f7ae00000) => /lib/ (0x0000003f78200000)          /lib64/ (0x0000003f77c00000) => /lib/ (0x0000003f78600000) => /lib/ (0x0000003f79600000)

    $ scanelf -n /usr/lib64/mozilla-firefox/firefox TYPE   NEEDED FILEET_EXEC,,,, /usr/lib64/mozilla-firefox/firefox

    fgrep sqlite /proc/`pidof firefox`/smaps3fb5600000-3fb5670000 r-xp 00000000 08:07 387045                         /usr/lib64/ ---p 00070000 08:07 387045                         /usr/lib64/ r--p 0006f000 08:07 387045                         /usr/lib64/ rw-p 00070000 08:07 387045                         /usr/lib64/


  9. Kent, that’s certainly good to hear, although I wouldn’t try them just yet ;)Just to make sure I clearly state how things are, I’ve had a bit of a chat with Benjamin Smedberg from Mozilla, and there are a few interesting notes:* the SQLite problem is indeed a problem with the source release, they should either rename or use versioning to make sure the symbols don’t collide (and thus both copies gets used properly); also it’s interesting to know that the version that “wins” is the Mozilla one anyway, not the system one;* RPATH is not used on official releases because they still support older versions of glibc that don’t provide $ORIGIN support; this is an important reason, but I think the right way would have been to check which versions do support $ORIGIN, and eventually fall back on the environment variable;* the reason why the source ebuild version does not have the launcher and the finally-linked executable like the official release is that I have the xulrunner USE flag enabled to make use of the shared copy of xulrunner in the system, and to make sure it’s switchable at runtime, it reads it from @/etc/gre.d@, to allow access from binary extensions as well.Seems like Mozilla is open to patches to solve these issues, at least with optional features for distributions, so I’ll see if I can spare enough time to work on those in the future.The one that concerns me the most is the third, but I have to look it up because as it is I don’t see what’s stopping anybody from just writing the final path inside xulrunner and then use a symbol to fetch it rather than finding it on a file.


  10. I’ve always been quite defensive over Firefox as it was the browser that gave me freedom 5 years ago when I was on Windows and things like Chrome didn’t exist. Plugins like Vimperator also caused me to find Firefox irreplacable. However recent glitches including slow Flash video playing and intensive CPU usage – as taken from a users point of view (I see you’re taking a developer standpoint here) really dissapoints.I’m currently on Aurora, and finding it quite nice. If Firefox worked on optimisation more I might switch back.


  11. imho, the one hope for linux is konqueror. I know it will probably never be very speedy, play nice with flash, or be too terribly stable given how unmaintained it is, but I can tell it is really trying to be a good browser, and is conceptually ahead of its time in many respects.Its QT; works with khtml; webkit continues to become more usable. It has novel features like split view; can have embedded components via kparts like konsole; can itself be embedded in other applications via kparts; supports transparent connections to many arbitrary protocols via KIO – an incredible feature imho; and lets not forget its other half – the Dolphin file browser component.It honestly has everything you would expect from a futuristic browser and then some. On the surface, all of its features even appear to be highly polished. Really the only things holding it back are:1) Its slow… really slow. A lot has to do with #2 below, but I think there are other inefficiencies with its rendering speed.2) It is incredibly difficult to make it play nice with flash. Rarely, it works directly with nsplugins, but most people must resort to running it inside kmplayer. Even when it does work and isn’t crashing, it is very very sluggish, and a huge memory hog.3) There is no large library of extensions and miscilanious plugins like noscript and adblock (somewhat less convenient equivalents to both are built in.) I like konqueror’s approach to these, but they are not yet up to par with firefox’s plugins. Webkit support needs to be improved and be more than simply an extension on top of konq. I haven’t yet gotten the webkit kpart to work with kmplayer embedded flash, and youtube doesn’t render correctly with khtml.4) crashy, unstable, did I mention slow?So yeah… In summary: Conceptually konq is an epic win. Performance-wise – fail. If only they had a better developer base to get these kinks worked out, particularly in rendering performance and accuracy, and better webkit and flash integration, it could really be leaps and bounds ahead of everything else out there – including firefox and safari.


  12. the sqlite problem is not just bad coding. i spent a day or 2 digging through source code in hopes of making an exploit involving an overloaded pref()’s call and their resource:/// capabilities. basically, i wanted to start changing the browsers user prefs with javascript: turn on automatic downloads, hide the download window, and execute the program.i had no luck with the overloaded prefs approach, but you can load firefoxs js libraries that interface with the sqlite database, which is where the user prefs are stored. im not sure how far you could take this, but for security reasons, it might be better to give malicious javascript code access to something other than a system process.preferably a black hole.


  13. There have been bugs since release 1. Bug reports, that is, and no one effen cares.After FF1, there are several major bugs still outstanding. I ran across two dozen when building a large web app.At the very least Mozilla, give me run-in and parse your XML correctly! You’re more an annoyance than IE sometimes. At least Opera fixes my bug reports even though they are riddled with them (the underdog always like to release beta prematurely.)GD!, switch to webkit. It’s the best engine.


  14. @Dan : You can’t be serious with konqueror. I really don’t want to compile that many dependencies.


  15. I recently upgraded my Firefox browser to 19.0 and the first time I open it crashes. I am a programmer so I was willing to check their code for errors to submit a corrections. Firefox browser consists of some of the worst code I’ve ever seen in my entire life! The majority of their code consists of partially working patches. To my knowledge the browser has been nicknamed Crashfox since 4.0. Funny how they still haven’t fixed that.If Firefox did not have any add-ons the real truth is nobody would use it. Living in the Silicon Valley there is lots of talk of dropping Firefox support since the new operations are hiding inside India, without giving U.S. jobs. I am no Microsoft fan but truth be told that Internet Explorer 10 surprisingly surpasses all browsers in every test. Chrome and Safari come next for 2nd and 3rd place. Unfortunately Firefox didn’t make the cut, and never will.I just feel bad for Linux only users, this is basically the only “functional” browser option. I am glad that Mozilla Firefox is going nowhere but downhill from here. It’s not fair when users get errors for clean valid code.R.I.P. Firefox


  16. Yes firefox is really that bad. It gives a bad name to the open source community. The big problem is that it was poorly written to begin with. As we programmers like to call it, “shit code”. The best thing would be to re-code firefox from scratch without 2 million patches. But lets face the facts they don’t have enough funding to do this and what programmers like to deal with such bad code.@JohnTheir move to India is their last attempt to get Firefox in a better state. What’s so sad about the situation is they are embarrassed and don’t even mention or acknowledge their new headquarters and offices on their website. When I emailed them asking why they didn’t update their page with the new offices listed. they replied “We are very busy updating our mozilla browsers and that’s our main priority.”. So basically yes… firefox is definitely going out the door, the back door very quietly, where nobody will notice their disappearance.


  17. Why a 2009 post and comments. Is there a point? Is it the same now? Nov 2014 or has Firefox come a long way since then or what? Yes there is a Chrome for Linux.I do wonder in the present if a long occurring problem of closing, thinking you closed Firefox and then opening it again and being told it is already open has anything to do with this?Latest Firefox is good and fast and handle allowing pop-up windows such as at Virgin Mobile site U.S. a lot better than Chrome. Also Firefox loads (on Linux at least) OpenGl 3D out of the box, chrome you have to go deep and set some default settings otherwise. Also though I stick with Chrome or Chrome Beta as default mostly due to extensions I use there, Firefox seems to be much less a memory hog while Chrome basically in desiring to be you desktop easily freezes a computer with over 20 windows opening at the same time…Goals ha!With the systemd fiasco going on in Linux, with Ubuntu dictating desktops like Microsoft that fix what isn’t broken and try to amalgamate phone, tablet, touch and desktop interfaces into ONE BIG MESS and apple always a monolithic exlusive now huge monopoly that overcharges for software it would appear no goals might be better than stupid, divisive fix what isn’t broken and make sure your software or codec doesn’t work on other systems or players…Linux and its outgrowth of inter operable software like VLC or Gimp or LibreOffice has been the best while it lasts.


  18. Microsoft in trying to accommodate all devices in one operating system even goes against their usual greedy strain of selling as OS for each device separately.Everyone especially say Adobe and Microsoft in the Office arena want to rent you usage of their programs in the cloud instead of you being able to actually buy the software and “own” a copy…modeling themselves like Television, Internet and cable companies where you pay for evanescent electrical phenomena for about 600 or more a year for telephone, or TV or internet so 1800 a year unless you get two of those say on a phone so 1200. Wrong path to follow long term because they are all going to get screwed out of ripping everyone off for between 30 and 50 years. Just watch.Linux still leads the free front and for all the current desktops flaws (with exceptions or just modifying back to what you like) steadily makes a more reliable product that installs more easily than ever, usually allows a side by side install in Ubuntu that can go perfectly and trumps the non-sense of windows updates which seem always to be repairs and less so improvements, and forced operating system upgrades obsolescing that latest past OS see Windows 7 even. Etc. Hope Linux can somehow stay the course.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s