Bug 135178 - JSDOMWindowShell leaks on pages with media elements
Summary: JSDOMWindowShell leaks on pages with media elements
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore JavaScript (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2014-07-22 14:49 PDT by Joseph Pecoraro
Modified: 2014-07-23 14:56 PDT (History)
17 users (show)

See Also:


Attachments
[PATCH] Proposed Fix (2.50 KB, patch)
2014-07-22 14:58 PDT, Joseph Pecoraro
buildbot: commit-queue-
Details | Formatted Diff | Diff
Archive of layout-test-results from webkit-ews-10 for mac-mountainlion-wk2 (537.20 KB, application/zip)
2014-07-22 15:53 PDT, Build Bot
no flags Details
[PATCH] Proposed Fix (3.44 KB, patch)
2014-07-22 17:07 PDT, Joseph Pecoraro
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph Pecoraro 2014-07-22 14:49:33 PDT
With MEDIA_CONTROLS_SCRIPT reloading a page with a <video> creates JSDOMWindowShell/JSGlobalObject objects that never get destroyed.

The window shell is created under HTMLMediaElement::ensureMediaControlsInjectedScript, but never destroyed.

(lldb) bt
  * frame #0: WebCore::ScriptController::createWindowShell(this=0x0000620000100240, world=0x0000600000103ba0) + 23 at ScriptController.cpp:112
    frame #1: WebCore::ScriptController::initScript(this=0x0000620000100240, world=0x0000600000103ba0) + 138 at ScriptController.cpp:229
    frame #2: WebCore::ScriptController::windowShell(this=0x0000620000100240, world=0x0000600000103ba0) + 199 at ScriptController.h:89
    frame #3: WebCore::ScriptController::globalObject(this=0x0000620000100240, world=0x0000600000103ba0) + 29 at ScriptController.h:98
    frame #4: WebCore::HTMLMediaElement::ensureMediaControlsInjectedScript(this=0x00000001130ad800) + 247 at HTMLMediaElement.cpp:5795
    frame #5: WebCore::HTMLMediaElement::updateCaptionContainer(this=0x00000001130ad800) + 124 at HTMLMediaElement.cpp:3717
    frame #6: WebCore::HTMLMediaElement::configureTextTrackGroup(this=0x00000001130ad800, group=0x00007fff5fbfcfd0) + 2505 at HTMLMediaElement.cpp:3676
    frame #7: WebCore::HTMLMediaElement::configureTextTracks(this=0x00000001130ad800) + 1309 at HTMLMediaElement.cpp:3848
    frame #8: WebCore::HTMLMediaElement::loadTimerFired(this=0x00000001130ad800, (null)=0x00000001130ad8c0) + 99 at HTMLMediaElement.cpp:796

Andreas pointed out that we should be calling clearWrappers on the DOMWrapperWorld. Doing so does clear the excess worlds.
Comment 1 Joseph Pecoraro 2014-07-22 14:50:44 PDT
<rdar://problem/17713033>
Comment 2 Joseph Pecoraro 2014-07-22 14:58:29 PDT
Created attachment 235317 [details]
[PATCH] Proposed Fix

I am somewhat concerned that other iterations over m_windowShells could trigger a GC that modifies m_windowShells. However they are far more straightforward than WebCore::ScriptController::clearWindowShell.

It also seems dangerous that ScriptCachedFrameData reaches directly in and iterates ScriptController.m_windowShells.
Comment 3 WebKit Commit Bot 2014-07-22 15:01:20 PDT
Attachment 235317 [details] did not pass style-queue:


ERROR: Source/WebCore/bindings/js/ScriptController.cpp:189:  Declaration has space between type name and * in JSDOMWindowShell *windowShell  [whitespace/declaration] [3]
Total errors found: 1 in 3 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 4 Build Bot 2014-07-22 15:53:27 PDT
Comment on attachment 235317 [details]
[PATCH] Proposed Fix

Attachment 235317 [details] did not pass mac-wk2-ews (mac-wk2):
Output: http://webkit-queues.appspot.com/results/6048076619841536

New failing tests:
media/track/add-and-remove-track.html
Comment 5 Build Bot 2014-07-22 15:53:31 PDT
Created attachment 235322 [details]
Archive of layout-test-results from webkit-ews-10 for mac-mountainlion-wk2

The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews.
Bot: webkit-ews-10  Port: mac-mountainlion-wk2  Platform: Mac OS X 10.8.5
Comment 6 Joseph Pecoraro 2014-07-22 17:00:22 PDT
I am unable to reproduce the crash the bots saw, but it appear stop be in the TestRunner InjectedBundle overflowing a Vector bounds:

    Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
    Exception Codes: KERN_INVALID_ADDRESS at 0x00000000bbadbeef

    Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
    0   com.apple.JavaScriptCore      	0x00000001090eb49e WTFCrash + 62 (Assertions.cpp:329)
    1   WebKitTestRunnerInjectedBundle	0x000000010cf53703 WTF::CrashOnOverflow::overflowed() + 9
    2   WebKitTestRunnerInjectedBundle	0x000000010cf562e4 WTR::InjectedBundle::page() const + 24 (InjectedBundle.cpp:134)
    3   WebKitTestRunnerInjectedBundle	0x000000010cf498a1 WTR::TestRunner::removeAllWebNotificationPermissions() + 27 (InjectedBundlePage.h:41)
    4   WebKitTestRunnerInjectedBundle	0x000000010cf56054 WTR::InjectedBundle::didReceiveMessage(OpaqueWKString const*, void const*) + 398 (Vector.h:610)
    5   com.apple.WebKit              	0x00000001080ca6d8 WebKit::InjectedBundleClient::didReceiveMessage(WebKit::InjectedBundle*, WTF::String const&, API::Object*) + 120 (WKSharedAPICast.h:130)
    6   com.apple.WebKit              	0x0000000108225bc5 WebKit::WebProcess::postInjectedBundleMessage(IPC::DataReference const&) + 135 (RefPtr.h:55)
    7   com.apple.WebKit              	0x000000010822f258 WebKit::WebProcess::didReceiveWebProcessMessage(IPC::Connection*, IPC::MessageDecoder&) + 2356 (HandleMessage.h:16)
    ...

Perhaps this is flakey on the bots or related to other tests running simultaneously.
Comment 7 Joseph Pecoraro 2014-07-22 17:07:10 PDT
Created attachment 235328 [details]
[PATCH] Proposed Fix
Comment 8 Oliver Hunt 2014-07-22 20:23:51 PDT
Comment on attachment 235328 [details]
[PATCH] Proposed Fix

View in context: https://bugs.webkit.org/attachment.cgi?id=235328&action=review

> Source/WebCore/bindings/js/ScriptController.cpp:189
> +    Vector<JSC::Strong<JSDOMWindowShell>> windowShells;
> +    copyValuesToVector(m_windowShells, windowShells);
> +
> +    for (size_t i = 0; i < windowShells.size(); ++i) {
> +        JSDOMWindowShell* windowShell = windowShells[i].get();

We must take this, file it as a separate bug as this code is otherwise sadly unsafe :(

> Source/WebCore/html/HTMLMediaElement.cpp:421
> +    if (m_isolatedWorld)
> +        m_isolatedWorld->clearWrappers();

This is wrong - it means if we ever destroy an htmlmediaelement we'll nuke all the dom wrappers
Comment 9 Andreas Kling 2014-07-22 20:35:08 PDT
(In reply to comment #8)
> 
> > Source/WebCore/html/HTMLMediaElement.cpp:421
> > +    if (m_isolatedWorld)
> > +        m_isolatedWorld->clearWrappers();
> 
> This is wrong - it means if we ever destroy an htmlmediaelement we'll nuke all the dom wrappers

Why is this wrong? It will only nuke the DOM wrappers inside the isolated world *created by* this media element.
Comment 10 Oliver Hunt 2014-07-22 21:08:17 PDT
(In reply to comment #9)
> (In reply to comment #8)
> > 
> > > Source/WebCore/html/HTMLMediaElement.cpp:421
> > > +    if (m_isolatedWorld)
> > > +        m_isolatedWorld->clearWrappers();
> > 
> > This is wrong - it means if we ever destroy an htmlmediaelement we'll nuke all the dom wrappers
> 
> Why is this wrong? It will only nuke the DOM wrappers inside the isolated world *created by* this media element.

Wait each media element has its own entirely self container world?!?!?
Comment 11 Oliver Hunt 2014-07-23 10:25:15 PDT
Comment on attachment 235328 [details]
[PATCH] Proposed Fix

Talked to Jer, this is in fact correct sorry :)

Minor concern - is it possible for an object in a media element's world to point to something that refs the element? That would still be a cycle that needs to be broken
Comment 12 WebKit Commit Bot 2014-07-23 10:57:36 PDT
Comment on attachment 235328 [details]
[PATCH] Proposed Fix

Clearing flags on attachment: 235328

Committed r171481: <http://trac.webkit.org/changeset/171481>
Comment 13 WebKit Commit Bot 2014-07-23 10:57:42 PDT
All reviewed patches have been landed.  Closing bug.
Comment 14 Geoffrey Garen 2014-07-23 14:17:13 PDT
Man, we really need to improve the isolated worlds API / default memory management.
Comment 15 Joseph Pecoraro 2014-07-23 14:27:52 PDT
I think there is another case of iterating m_windowShells when it could be mutated in ScriptController::updateDocument:
<http://build.webkit.org/results/Apple%20Mavericks%20Debug%20WK2%20(Tests)/r171485%20(5831)/fast/html/details-nested-1-crash-log.txt>

I'll file a follow-up.
Comment 16 Joseph Pecoraro 2014-07-23 14:56:05 PDT
<https://webkit.org/b/135211> ScriptController::updateDocument ASSERT mutating map while iterating map