Bug 30510

Summary: Serializing a jQuery Object with jsDump can often kill the computer
Product: WebKit Reporter: Martin Häcker <spamfaenger>
Component: JavaScriptCoreAssignee: Nobody <webkit-unassigned>
Status: UNCONFIRMED ---    
Severity: Normal CC: mrowe
Priority: P2 Keywords: InRadar
Version: 528+ (Nightly build)   
Hardware: PC   
OS: OS X 10.5   
Attachments:
Description Flags
Showcase of the memory leak
none
Test that works in Firefox none

Description Martin Häcker 2009-10-19 04:43:24 PDT
There are mostly two scenarios that play out here:

a) The "slow script warning" kicks in and after the offered abort of the script Safari uses _lots_ of megabytes more memory that seems to be only reclaimable by restarting the browser or
b) The computer just comes to a grinding halt as it is swapping gigabytes of memory in and out. If I am fast enough I can usually kill Safari before my mashine doesn't respond in any way anymore - but I need to be quick for this.

I think that this should not be possible - if a webpage is using some gigabytes of memory in a computation, Safari should protect my computer from getting bogged down by this.

Some notes on the setup. I haven't yet reduced this down completely, but here's how it happens.

Using: jQuery 1.3.2, jQuery-UI 1.7.2, jsDump 1.0.0

I have a page with some <dl><dt/><dd/><dd/></dl> and then do some code roughly equivalent to this:

$('dl').draggable()
jsDump.parse($('dl').data('draggable'))

(Actually that is one of my unittests failing and then trying to stringify the results of that data-call).

So please fix it.

Regards,
Martin
Comment 1 Alexey Proskuryakov 2009-10-19 10:26:44 PDT
<rdar://problem/7315422>
Comment 2 Mark Rowe (bdash) 2009-10-19 11:37:12 PDT
Can you please attach a simple test page that demonstrates the problem?
Comment 3 Martin Häcker 2009-10-20 01:25:47 PDT
Created attachment 41489 [details]
Showcase of the memory leak

I was able to reproduce the memory leak situation in this small setup - however I was not able to reduce the "brings my computer to a complete halt" scenario yet.

Sorry - I know it has to be a very similar situation, but I haven't found the magic sauce yet.

Something I observed while trying this out: It seems that this code leaks even more memory even after the "slow script warning" is used to kill this errant java-script. I will not pursue this further as I don't have the time, but it might make sense to monitor WebKit even after the script is killed.

Regards,
Martin
Comment 4 Mark Rowe (bdash) 2009-10-20 01:29:53 PDT
I suspect that this stems from the fact that $('dl').sortable().data('sortable’) returns a self-referential data structure.  $('dl').sortable().data(‘sortable’).containers[0] === $('dl').sortable().data('sortable’).  Code that attempted to process this data structure without handling recursion would demonstrate the behavior you mention.
Comment 5 Mark Rowe (bdash) 2009-10-20 01:35:06 PDT
The sample page doesn’t appear to work in Firefox which makes it hard to determine whether we’re doing something wrong or if the script is at fault.  Firefox throws an exception saying:

$("dl").sortable is not a function.
Comment 6 Mark Rowe (bdash) 2009-10-20 01:42:31 PDT
After tweaking it a little bit more I managed to convince this to work in Firefox too.  Firefox dies saying:

Error: too much recursion
Source File: http://flesler-plugins.googlecode.com/files/jsDump-1.0.0.js
Line: 45

This indicates that the code in jsDump is at fault for not handling data structures with cycles correctly.  I suspect WebKit uses more memory and runs in to the slow script dialog before it hits its much higher maximum recursion depth (> 45,000 compared to Firefox’s 3,000).
Comment 7 Mark Rowe (bdash) 2009-10-20 01:47:30 PDT
Created attachment 41490 [details]
Test that works in Firefox
Comment 8 Martin Häcker 2009-10-21 15:16:08 PDT
Some quick tests on my part confirm this analysis.

I would think that what webkit needs is some kind of limit that brings up the slow-script-warning before the memory use brings down the system to a screetching and complete halt. I would imagine something like if a webpage uses more than half the complete ram of the system could be the point when a dialogue offering to stop the script could be shown. (Probably even way before that)

Regards,
Martin