a crazy bug
Yesterday I was working on a bug that was kind of interesting. Since my friend Tony was talking about writing an article for his blog, I thought I would write down what I've been doing here.
I was told about a bug in LibreJS – you couldn't load reddit.com when using the LibreJS add-on with GNU IceCat and Trisquel. Wow.... I need to fix this immediately.
The symptom of the problem was that the browser froze. Each voting arrow on reddit has an attribute that looks like this:
onclick="click_thing(this)"Each of these scripts needs to be processed by LibreJS. The first time it's processed, it computes a hash of the script so the results can be saved for subsequent identical scripts.
Then I saw something suspicious in the debug log. I've linked to it here because there's a lot of text. Immediately at the top it says "too much recursion". If you scroll all the way to the right, you can see the call stack repeating itself many times, confirming the runtime's complaint.
I thought, "Great.. I've found the problem. I've seen
this before it must be an infinite loop." I spent a few
hours trying to fit the recursive loop into my head –
what is it actually doing, and what special if
statement should I enter to just break out of it, in this
specific case? All these strange onclick
scripts
must be triggering an unhandled case in LibreJS.
But reddit was loading fine in Mac OS. That was an important
point that I had forgotten about. Maybe "Too much
recursion" just meant too much recursion for this specific
system, and the loop wasn't actually infinite. After reading
more about this JavaScript error, I found that using
setTimeout
can reset the call stack. I
tried this out,
and it worked.
And now you can read reddit.com when you're using LibreJS with GNU IceCat on Trisquel Linux.