December 26th, 2005
Recently, Firefox has been maxing out my CPU “when I have more than three tabs open.” As is typical with bug reports from users, this one is very poorly worded and essentially useless. It turns out that that was not a good explanation of what was going on. I messed around a little more and figured out that the problem had these characteristics:
- The CPU was maxed out on any ESPN.com page.
- Thread #0 was the offending thread.
- Firefox’s working set increased steadily while looking at ESPN.
- Firefox eventually crashes with an A/V if the browser is left on ESPN.
I’m not sure if this is some strange interaction of my specific combination of extensions and settings, or if this happens for all Firefox users. This seems like a possible security vulnerability, but I can’t say one way or the other.
I suppose I could have downloaded and compiled the source code for Firefox to figure things out, but that was way more effort than I felt like giving. I did managed to debug and fix this issue for myself—without source or symbols—which I think makes for an interesting writeup.
- Although this kind person has done his own workaround for 1.5, it was either brought to its knees by the ESPN site or was broken by something else.
I attached to Firefox.exe in Windbg and started randomly breaking in and checking on thread zero while the spike was in progress. Sometimes, frames in the js3250 module were on the stack:
0:009> ~0k ChildEBP RetAddr WARNING: Stack unwind information not available. Following frames may be wrong. 0012f97c 6009db8b js3250!JSLL_MinInt+0x45e2 0012f9c8 6009cdd9 js3250!js_GetSrcNoteOffset+0x5358 0012f9f0 600c7c01 js3250!js_GetSrcNoteOffset+0x45a6 0012fa08 600856b5 js3250!js_GetScriptLineExtent+0x39e6 0012fa28 600b036f js3250!JS_NewStringCopyZ+0x44 0012fa40 600b3e93 js3250!js_FindProperty+0x26c5
x js3250!* in Windbg) — it appeared as though this module was implemented as a few dozen C-style exports.
0:009> x js3250!*Call*Function* 6008541f js3250!JS_CallFunction (<no parameter info>) 60085464 js3250!JS_CallFunctionName (<no parameter info>) 600854ff js3250!JS_CallFunctionValue (<no parameter info>)
I set a breakpoint on all of these.
0:009> bm js3250!*Call*Function* 1: 6008541f @!!"js3250!JS_CallFunction" 2: 60085464 @!!"js3250!JS_CallFunctionName" 3: 600854ff @!!"js3250!JS_CallFunctionValue"
I looked at some of the stacks when these functions were called, and I noticed this pretty far down:
0012fc7c 00534e18 js3250!JS_EvaluateUCScriptForPrincipals+0x70
As an only slightly educated guess, I used the Adblock extension to block this script.
After reloading the page, the problem was gone! There don’t seem to be any site-breaking problems associated with turning this script off. This is all or part of the “ESPN Motion” business that tries to display sound and video on the site. Hey, ESPN: this is a terrible idea in the first place. Your website shouldn’t start yelling at me when I visit it. It’s no excuse for Firefox to A/V, but I thought everyone with a three-digit IQ stopped doing this in 1996.