Bug 78240

Summary: Callbacks during deferred loads
Product: WebKit Reporter: jochen
Component: New BugsAssignee: jochen
Status: NEW ---    
Severity: Normal CC: abarth, andersca, ap, fishd, priyajeet.hora
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on: 78486    
Bug Blocks:    
Attachments:
Description Flags
Patch (test only) none

Description jochen 2012-02-09 07:53:06 PST
Callbacks during deferred loads
Comment 1 jochen 2012-02-09 07:53:46 PST
Created attachment 126304 [details]
Patch (test only)
Comment 2 jochen 2012-02-09 07:59:01 PST
This test-case triggers a ton of problems for me:

On chromium-linux-dbg, I get an ASSERT() about callbacks during deferred load:


ASSERTION FAILED: shouldLoadAsEmptyDocument(r.url()) || !defersLoading()
../../Source/WebCore/loader/MainResourceLoader.cpp(386) : virtual void WebCore::MainResourceLoader::didReceiveResponse(const WebCore::ResourceResponse&)

        WebCore::MainResourceLoader::didReceiveResponse() [0x1acf32c]
        WebCore::ResourceLoader::didReceiveResponse() [0x1ae26cd]
        WebCore::ResourceHandleInternal::didReceiveResponse() [0x53bb87]
        webkit_glue::WebURLLoaderImpl::Context::OnReceivedResponse() [0x5cfe15]
        webkit_glue::WebURLLoaderImpl::Context::HandleDataURL() [0x5d0932]
        base::internal::RunnableAdapter<>::Run() [0x5d2047]
        base::internal::InvokeHelper<>::MakeItSo() [0x5d1fde]
        base::internal::Invoker<>::Run() [0x5d1f69]
        base::Callback<>::Run() [0x5a233d]
        MessageLoop::RunTask() [0x11c6ee8]
        MessageLoop::DeferOrRunPendingTask() [0x11c6fff]
        MessageLoop::DoWork() [0x11c7821]
        base::MessagePumpGlib::HandleDispatch() [0x1227537]
        (anonymous namespace)::WorkSourceDispatch() [0x1226a83]
        0x7fc1315ba8c2
        0x7fc1315be748
        0x7fc1315be8fc
        base::MessagePumpGlib::RunWithDispatcher() [0x12271e6]
        base::MessagePumpGlib::Run() [0x1227614]
        MessageLoop::RunInternal() [0x11c6ba3]
        MessageLoop::RunHandler() [0x11c6a56]
        MessageLoop::Run() [0x11c638b]
        webkit_support::RunMessageLoop() [0x4a3c48]
        WebViewHost::runModal() [0x47bfaa]
        WebKit::ChromeClientImpl::runModal() [0x5122f6]
        WebCore::Chrome::runModal() [0x1b29a5c]
        WebCore::DOMWindow::showModalDialog() [0x1b438ff]
        WebCore::V8DOMWindow::showModalDialogCallback() [0x1870479]
        v8::internal::HandleApiCallHelper<>() [0x12dbf53]
        v8::internal::Builtin_Impl_HandleApiCall() [0x12d69eb]
        v8::internal::Builtin_HandleApiCall() [0x12d69bc]

On chromium-linux-rel, the test passes

On chromium-mac-{rel,dbg}, the assertion is not triggered, but DumpRenderTree never exists the nested message loop

On mac-dbg, the test crashes:

0   DumpRenderTree                	0x000000010c64289b -[UIDelegate webView:createWebViewWithRequest:] + 155 (UIDelegate.mm:142)
1   com.apple.WebKit              	0x000000010d3a60d0 _ZL12CallDelegateP7WebViewP11objc_objectP13objc_selectorS2_ + 176 (WebDelegateImplementationCaching.mm:103)
2   com.apple.WebKit              	0x000000010d3a6015 CallUIDelegate(WebView*, objc_selector*, objc_object*) + 69 (WebDelegateImplementationCaching.mm:439)
3   com.apple.WebKit              	0x000000010d393c2b WebChromeClient::createWindow(WebCore::Frame*, WebCore::FrameLoadRequest const&, WebCore::WindowFeatures const&, WebCore::NavigationAction const&) + 1995 (WebChromeClient.mm:273)
4   com.apple.WebCore             	0x000000010db3d8f0 WebCore::Chrome::createWindow(WebCore::Frame*, WebCore::FrameLoadRequest const&, WebCore::WindowFeatures const&, WebCore::NavigationAction const&) const + 96 (Chrome.cpp:188)
5   com.apple.WebCore             	0x000000010e07bfc6 WebCore::createWindow(WebCore::Frame*, WebCore::Frame*, WebCore::FrameLoadRequest const&, WebCore::WindowFeatures const&, bool&) + 822 (FrameLoader.cpp:3345)
6   com.apple.WebCore             	0x000000010df4b2a1 WebCore::DOMWindow::createWindow(WTF::String const&, WTF::AtomicString const&, WebCore::WindowFeatures const&, WebCore::DOMWindow*, WebCore::Frame*, WebCore::Frame*, void (*)(WebCore::DOMWindow*, void*), void*) + 753 (DOMWindow.cpp:1786)
7   com.apple.WebCore             	0x000000010df4be88 WebCore::DOMWindow::showModalDialog(WTF::String const&, WTF::String const&, WebCore::DOMWindow*, WebCore::DOMWindow*, void (*)(WebCore::DOMWindow*, void*), void*) + 440 (DOMWindow.cpp:1892)
8   com.apple.WebCore             	0x000000010e52e662 WebCore::JSDOMWindow::showModalDialog(JSC::ExecState*) + 402 (JSDOMWindowCustom.cpp:565)
9   com.apple.WebCore             	0x000000010e51daf5 WebCore::jsDOMWindowPrototypeFunctionShowModalDialog(JSC::ExecState*) + 389 (JSDOMWindow.cpp:10962)
10  ???                           	0x00002ebac3001218 0 + 51379670356504
11  com.apple.JavaScriptCore      	0x000000010c9a03a9 JSC::JITCode::execute(JSC::RegisterFile*, JSC::ExecState*, JSC::JSGlobalData*) + 121 (JITCode.h:115)
12  com.apple.JavaScriptCore      	0x000000010c99cda6 JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 1766 (Interpreter.cpp:1083)
13  com.apple.JavaScriptCore      	0x000000010c85facb JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 315 (CallData.cpp:39)
14  com.apple.WebCore             	0x000000010e420c33 WebCore::JSMainThreadExecState::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 179 (JSMainThreadExecState.h:56)
15  com.apple.WebCore             	0x000000010e420b04 WebCore::JSMainThreadExecState::instrumentedCall(WebCore::Page*, JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 420 (JSMainThreadExecState.h:75)
16  com.apple.WebCore             	0x000000010e55d618 WebCore::JSEventListener::handleEvent(WebCore::ScriptExecutionContext*, WebCore::Event*) + 1432 (JSEventListener.cpp:124)
17  com.apple.WebCore             	0x000000010dfde359 WebCore::EventTarget::fireEventListeners(WebCore::Event*, WebCore::EventTargetData*, WTF::Vector<WebCore::RegisteredEventListener, 1ul>&) + 393 (EventTarget.cpp:232)
18  com.apple.WebCore             	0x000000010dfde19b WebCore::EventTarget::fireEventListeners(WebCore::Event*) + 331 (EventTarget.cpp:200)
19  com.apple.WebCore             	0x000000010df43f1a WebCore::DOMWindow::dispatchEvent(WTF::PassRefPtr<WebCore::Event>, WTF::PassRefPtr<WebCore::EventTarget>) + 362 (DOMWindow.cpp:1632)
20  com.apple.WebCore             	0x000000010df4a65b WebCore::DOMWindow::dispatchLoadEvent() + 395 (DOMWindow.cpp:1606)
21  com.apple.WebCore             	0x000000010ddc2ac2 WebCore::Document::dispatchWindowLoadEvent() + 146 (Document.cpp:3720)
22  com.apple.WebCore             	0x000000010ddbfa45 WebCore::Document::implicitClose() + 501 (Document.cpp:2271)
23  com.apple.WebCore             	0x000000010e06ef5b WebCore::FrameLoader::checkCallImplicitClose() + 155 (FrameLoader.cpp:797)
24  com.apple.WebCore             	0x000000010e06ed44 WebCore::FrameLoader::checkCompleted() + 308 (FrameLoader.cpp:744)
25  com.apple.WebCore             	0x000000010e06f034 WebCore::FrameLoader::completed() + 196 (FrameLoader.cpp:1085)
26  com.apple.WebCore             	0x000000010e06ed61 WebCore::FrameLoader::checkCompleted() + 337 (FrameLoader.cpp:747)
27  com.apple.WebCore             	0x000000010e06da53 WebCore::FrameLoader::finishedParsing() + 179 (FrameLoader.cpp:678)
28  com.apple.WebCore             	0x000000010ddcb58f WebCore::Document::finishedParsing() + 591 (Document.cpp:4464)
29  com.apple.WebCore             	0x000000010e246bb4 WebCore::HTMLTreeBuilder::finished() + 148 (HTMLTreeBuilder.cpp:2821)
30  com.apple.WebCore             	0x000000010e17dfc3 WebCore::HTMLDocumentParser::end() + 227 (HTMLDocumentParser.cpp:382)
31  com.apple.WebCore             	0x000000010e17cee6 WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() + 278 (HTMLDocumentParser.cpp:391)
32  com.apple.WebCore             	0x000000010e17ccbc WebCore::HTMLDocumentParser::prepareToStopParsing() + 268 (HTMLDocumentParser.cpp:154)
33  com.apple.WebCore             	0x000000010e17e013 WebCore::HTMLDocumentParser::attemptToEnd() + 67 (HTMLDocumentParser.cpp:403)
34  com.apple.WebCore             	0x000000010e17e068 WebCore::HTMLDocumentParser::finish() + 72 (HTMLDocumentParser.cpp:430)
35  com.apple.WebCore             	0x000000010de24dfa WebCore::DocumentWriter::endIfNotLoadingMainResource() + 282 (DocumentWriter.cpp:234)
36  com.apple.WebCore             	0x000000010de24410 WebCore::DocumentWriter::end() + 48 (DocumentWriter.cpp:213)
37  com.apple.WebCore             	0x000000010de03cab WebCore::DocumentLoader::finishedLoading() + 91 (DocumentLoader.cpp:296)
38  com.apple.WebCore             	0x000000010e078341 WebCore::FrameLoader::finishedLoading() + 81 (FrameLoader.cpp:2071)
39  com.apple.WebCore             	0x000000010e9c2c6e WebCore::MainResourceLoader::didFinishLoading(double) + 318 (MainResourceLoader.cpp:485)
40  com.apple.WebCore             	0x000000010ed79476 WebCore::ResourceLoader::didFinishLoading(WebCore::ResourceHandle*, double) + 198 (ResourceLoader.cpp:452)
41  com.apple.WebCore             	0x000000010ed75cf5 -[WebCoreResourceHandleAsDelegate connectionDidFinishLoading:] + 261 (ResourceHandleMac.mm:887)
42  com.apple.Foundation          	0x00007fff90b03712 ___NSURLConnectionDidFinishLoading_block_invoke_1 + 122
43  com.apple.Foundation          	0x00007fff90b03692 _NSURLConnectionDidFinishLoading + 81
44  com.apple.CFNetwork           	0x00007fff91645ee2 URLConnectionClient::_clientDidFinishLoading(URLConnectionClient::ClientConnectionEventQueue*) + 296
45  com.apple.CFNetwork           	0x00007fff916f5d0e URLConnectionClient::ClientConnectionEventQueue::processAllEventsAndConsumePayload(XConnectionEventInfo<XClientEvent, XClientEventParams>*, long) + 862
46  com.apple.CFNetwork           	0x00007fff916f5efa URLConnectionClient::ClientConnectionEventQueue::processAllEventsAndConsumePayload(XConnectionEventInfo<XClientEvent, XClientEventParams>*, long) + 1354
47  com.apple.CFNetwork           	0x00007fff91620dfd URLConnectionClient::processEvents() + 185
48  com.apple.CFNetwork           	0x00007fff91620ca2 MultiplexerSource::perform() + 212
49  com.apple.CoreFoundation      	0x00007fff8cc3db51 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
50  com.apple.CoreFoundation      	0x00007fff8cc3d3bd __CFRunLoopDoSources0 + 253
51  com.apple.CoreFoundation      	0x00007fff8cc641a9 __CFRunLoopRun + 905
52  com.apple.CoreFoundation      	0x00007fff8cc63ae6 CFRunLoopRunSpecific + 230
53  com.apple.Foundation          	0x00007fff90aa704f -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 267
54  DumpRenderTree                	0x000000010c60844b _ZL7runTestRKSs + 3067 (DumpRenderTree.mm:1348)
55  DumpRenderTree                	0x000000010c60778f _ZL20runTestingServerLoopv + 223 (DumpRenderTree.mm:811)
56  DumpRenderTree                	0x000000010c607094 dumpRenderTree(int, char const**) + 356 (DumpRenderTree.mm:860)
57  DumpRenderTree                	0x000000010c608bec main + 124 (DumpRenderTree.mm:898)
58  DumpRenderTree                	0x000000010c5f3654 start + 52

On mac-wk2-dbg, all tests with showModalDialog are skipped anyway
Comment 3 jochen 2012-02-09 15:00:11 PST
So I figured out that the hang on chromium-mac is due to a difference in how message pump is implemented in chromium-mac (vs. the other chromium flavors): In the attached test, two nested message loops are started. On chromium-mac, the termination signals are both send to the second nested message loop, so the first nested message loop just stays around forever...
Comment 4 Adam Barth 2012-02-09 15:46:18 PST
+fishd for fun with showModalDialog and nested message loop
Comment 5 jochen 2012-02-10 02:23:02 PST
ok, here's what's happening on chromium-mac at least

the attached test loads to iframes that each have a frameset with a single frame with a data: url in it. The frameset has an onload handler that opens a modal dialog.

When the first frameset finishes loading, the first onload handler is executed, and a nested message loop is started.

On this nested message loop, however, the resource response for the second frameset's data: url is coming in, resulting in the second onload handler being called on the nested message loop inside the first onload handler.

This should not happen, as the dialog is supposed to be modal.
Comment 6 Darin Fisher (:fishd, Google) 2012-02-11 11:09:05 PST
On the Chromium side, we should just run showModalDialog in an app-modal container, as we do for alert.  It is a long-standing bug that we do not.  I think we should also seriously consider removing showModalDialog from the platform.
Comment 7 jochen 2012-02-11 11:18:47 PST
(In reply to comment #6)
> On the Chromium side, we should just run showModalDialog in an app-modal container, as we do for alert.  It is a long-standing bug that we do not.  I think we should also seriously consider removing showModalDialog from the platform.

Would this be enough? I think we might even need to render the dialog in a different process?
Comment 8 Adam Barth 2012-02-11 13:01:43 PST
> Would this be enough? I think we might even need to render the dialog in a different process?

showModalDialog has a return value, which we'd need to structured clone across processes (which should be doable).