WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
UNCONFIRMED
92198
Web Inspector: debugging long-running scripts with conditional breakpoints consumes huge amounts of memory
https://bugs.webkit.org/show_bug.cgi?id=92198
Summary
Web Inspector: debugging long-running scripts with conditional breakpoints co...
Félix Cloutier
Reported
2012-07-24 20:10:06 PDT
When uninterrupted, long-running scripts execute under the Javascript debugger, and those scripts have conditional breakpoints, WebProcess will consume huge amounts of memory for seemingly little reason. On the test case attached, with the conditional breakpoints, memory consumption continually grows to the point where there's no more free memory available. With the conditional breakpoints off, memory usage remains about stable. STEPS TO REPRODUCE 1. Launch the attached web page 2. Open the Web inspector, start the debugger 3. Add 4 conditional breakpoints, one per line inside the `for` loop of the `foo` function, and give them an unlikely condition (`i == -1` for instance) 4. With your favorite diagnostics tool, watch WebProcess eat up all the memory it can
Attachments
The test case
(682 bytes, text/html)
2012-07-24 20:10 PDT
,
Félix Cloutier
no flags
Details
Patch
(4.84 KB, patch)
2012-12-13 00:37 PST
,
Peter Wang
yurys
: review-
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Félix Cloutier
Comment 1
2012-07-24 20:10:35 PDT
Created
attachment 154228
[details]
The test case
Peter Wang
Comment 2
2012-12-13 00:28:10 PST
This problem is more obvious in memory-limited environment (e.g. mobile). The root reason is that, for failed condition of breakpoint, JSC doesn't run the EventLoop, so in a dense loop of js code, there is no chance to recycle garbage caused by evaluating the breakpoint's condition. There is an interesting test. if you put a normal breakpoint after the breakpoint with failed condition, the GC is working well. Since for a success breakpoint JSC run an EventLoop.
Peter Wang
Comment 3
2012-12-13 00:37:24 PST
Created
attachment 179222
[details]
Patch
Yury Semikhatsky
Comment 4
2012-12-13 00:49:50 PST
Comment on
attachment 179222
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=179222&action=review
> Source/WebCore/ChangeLog:11 > + No new test case.
Can you add a layout test for this? Since the problem is on the back-end you can add a protocol test for it(LayoutTests/inspector-protocol)
Peter Wang
Comment 5
2012-12-13 01:04:03 PST
(In reply to
comment #4
)
> (From update of
attachment 179222
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=179222&action=review
> > > Source/WebCore/ChangeLog:11 > > + No new test case. > > Can you add a layout test for this? Since the problem is on the back-end you can add a protocol test for it(LayoutTests/inspector-protocol)
ok. Let me a try.
Yury Semikhatsky
Comment 6
2012-12-13 01:19:46 PST
(In reply to
comment #2
)
> This problem is more obvious in memory-limited environment (e.g. mobile). > > The root reason is that, for failed condition of breakpoint, JSC doesn't run the EventLoop, so in a dense loop of js code, there is no chance to recycle garbage caused by evaluating the breakpoint's condition. >
It sounds weird that the issue is specific to breakpoint conditions. How does it work in case of eval producing a lot of garbage in a tight loop in user code?
> There is an interesting test. if you put a normal breakpoint after the breakpoint with failed condition, the GC is working well. Since for a success breakpoint JSC run an EventLoop.
Peter Wang
Comment 7
2012-12-13 18:55:24 PST
(In reply to
comment #6
)
> (In reply to
comment #2
) > > This problem is more obvious in memory-limited environment (e.g. mobile). > > > > The root reason is that, for failed condition of breakpoint, JSC doesn't run the EventLoop, so in a dense loop of js code, there is no chance to recycle garbage caused by evaluating the breakpoint's condition. > > > It sounds weird that the issue is specific to breakpoint conditions. How does it work in case of eval producing a lot of garbage in a tight loop in user code? >
Sorry to reply so late, since I spent some time to investigate the related code of JSC. For the code like this: for (var i=0;i<0xfffff;i++) { ... eval("..."); ... } The "EvalExecutable" is allocated just once and saved as an argument of current callFrame (Interpreter.cpp:149). But to evaluate the condition of breakpoint, the DebuggerCallFrame::evaluate is invoked, the "EvalExecutable" is allocated every time. Maybe, because it's difficult to bind the breakpoint-condition's string with a certain callFrame.
Yury Semikhatsky
Comment 8
2012-12-14 01:02:09 PST
(In reply to
comment #7
)
> (In reply to
comment #6
) > > (In reply to
comment #2
) > > > This problem is more obvious in memory-limited environment (e.g. mobile). > > > > > > The root reason is that, for failed condition of breakpoint, JSC doesn't run the EventLoop, so in a dense loop of js code, there is no chance to recycle garbage caused by evaluating the breakpoint's condition. > > > > > It sounds weird that the issue is specific to breakpoint conditions. How does it work in case of eval producing a lot of garbage in a tight loop in user code? > > > Sorry to reply so late, since I spent some time to investigate the related code of JSC. For the code like this: > for (var i=0;i<0xfffff;i++) { > ... > eval("..."); > ... > } > The "EvalExecutable" is allocated just once and saved as an argument of current callFrame (Interpreter.cpp:149). > > But to evaluate the condition of breakpoint, the DebuggerCallFrame::evaluate is invoked, the "EvalExecutable" is allocated every time. Maybe, because it's difficult to bind the breakpoint-condition's string with a certain callFrame.
Why JSC cannot run GC automatically during the breakpoint condition evaluation if it needs to free some memory? We need someone who understands JSC garbage collector details to look at this change.
Peter Wang
Comment 9
2012-12-14 01:16:49 PST
(In reply to
comment #8
)
> (In reply to
comment #7
) > > (In reply to
comment #6
) > > > (In reply to
comment #2
) > > > > This problem is more obvious in memory-limited environment (e.g. mobile). > > > > > > > > The root reason is that, for failed condition of breakpoint, JSC doesn't run the EventLoop, so in a dense loop of js code, there is no chance to recycle garbage caused by evaluating the breakpoint's condition. > > > > > > > It sounds weird that the issue is specific to breakpoint conditions. How does it work in case of eval producing a lot of garbage in a tight loop in user code? > > > > > Sorry to reply so late, since I spent some time to investigate the related code of JSC. For the code like this: > > for (var i=0;i<0xfffff;i++) { > > ... > > eval("..."); > > ... > > } > > The "EvalExecutable" is allocated just once and saved as an argument of current callFrame (Interpreter.cpp:149). > > > > But to evaluate the condition of breakpoint, the DebuggerCallFrame::evaluate is invoked, the "EvalExecutable" is allocated every time. Maybe, because it's difficult to bind the breakpoint-condition's string with a certain callFrame. > > Why JSC cannot run GC automatically during the breakpoint condition evaluation if it needs to free some memory? We need someone who understands JSC garbage collector details to look at this change.
I'm not expert of it. It depends on the strategy of port, usually JSC does GC with a interval-changeable timer. So need to run EventLoop to handle the timer message. I believe the design of JSC takes repeat "eval()" into account, but the mechanism of debugger works-around it. Welcome JSC's experts to have a look.
Brian Burg
Comment 10
2014-11-29 19:18:15 PST
This still repros on TOT.
Radar WebKit Bug Importer
Comment 11
2014-11-29 19:18:31 PST
<
rdar://problem/19096505
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug