SEGV_MAPERR when calling print() on unload. |
||||||
Issue descriptionChromium: 59.0.3055.0 (Developer Build) (64-bit) Revision: 991596180e69f17e1bc3828061b420821194031d OS: Linux What steps will reproduce the problem? (1) Navigate to <body onUnload="print()"></body> (2) Go back. Then, you will see an error on the console: Received signal 11 SEGV_MAPERR 000000000080 #0 0x2b033ee94aab base::debug::StackTrace::StackTrace() #1 0x2b033ee937ac base::debug::StackTrace::StackTrace() #2 0x2b033ee945bf base::debug::(anonymous namespace)::StackDumpSignalHandler() #3 0x2b033eb00330 <unknown> #4 0x2b034f770c49 blink::Frame::setIsLoading() #5 0x2b034f770523 blink::WebRemoteFrameImpl::didStopLoading() #6 0x2b0344d7edfd content::RenderFrameProxy::OnDidStopLoading() #7 0x2b0342cab741 _ZN4base20DispatchToMethodImplIPN7content14GpuChildThreadEMS2_FvvERKSt5tupleIJEEJEEEvRKT_T0_OT1_NS_13IndexSequenceIJXspT2_EEEE #8 0x2b0342cab6b0 _ZN4base16DispatchToMethodIPN7content14GpuChildThreadEMS2_FvvERKSt5tupleIJEEEEvRKT_T0_OT1_ #9 0x2b0344d86caf _ZN3IPC16DispatchToMethodIN7content16RenderFrameProxyEMS2_FvvEvSt5tupleIJEEEEvPT_T0_PT1_RKT2_ #10 0x2b0344d81df3 _ZN3IPC8MessageTI28FrameMsg_DidStopLoading_MetaSt5tupleIJEEvE8DispatchIN7content16RenderFrameProxyES7_vMS7_FvvEEEbPKNS_7MessageEPT_PT0_PT1_T2_ #11 0x2b0344d7dfd8 content::RenderFrameProxy::OnMessageReceived() #12 0x2b0340cb196b IPC::MessageRouter::RouteMessage() #13 0x2b0342d6da28 content::ChildThreadImpl::ChildThreadMessageRouter::RouteMessage() #14 0x2b0340cb18ee IPC::MessageRouter::OnMessageReceived() #15 0x2b0342d71cc7 content::ChildThreadImpl::OnMessageReceived() #16 0x2b0340c5c838 IPC::ChannelProxy::Context::OnDispatchMessage() #17 0x2b0340c6261f _ZN4base8internal13FunctorTraitsIMN3IPC12ChannelProxy7ContextEFvRKNS2_7MessageEEvE6InvokeIRK13scoped_refptrIS4_EJS7_EEEvS9_OT_DpOT0_ #18 0x2b0340c62506 _ZN4base8internal12InvokeHelperILb0EvE8MakeItSoIRKMN3IPC12ChannelProxy7ContextEFvRKNS4_7MessageEEJRK13scoped_refptrIS6_ES9_EEEvOT_DpOT0_ #19 0x2b0340c62493 _ZN4base8internal7InvokerINS0_9BindStateIMN3IPC12ChannelProxy7ContextEFvRKNS3_7MessageEEJ13scoped_refptrIS5_ES6_EEEFvvEE7RunImplIRKSA_RKSt5tupleIJSC_S6_EEJLm0ELm1EEEEvOT_OT0_NS_13IndexSequenceIJXspT1_EEEE #20 0x2b0340c623ac _ZN4base8internal7InvokerINS0_9BindStateIMN3IPC12ChannelProxy7ContextEFvRKNS3_7MessageEEJ13scoped_refptrIS5_ES6_EEEFvvEE3RunEPNS0_13BindStateBaseE #21 0x2b033ee9afee _ZNO4base8CallbackIFvvELNS_8internal8CopyModeE0ELNS2_10RepeatModeE0EE3RunEv #22 0x2b033ee9a72e base::debug::TaskAnnotator::RunTask() #23 0x2b034eb7ecc6 blink::scheduler::TaskQueueManager::ProcessTaskFromWorkQueue() #24 0x2b034eb7bdbd blink::scheduler::TaskQueueManager::DoWork() #25 0x2b034eb86ed4 _ZN4base8internal13FunctorTraitsIMN5blink9scheduler16TaskQueueManagerEFvbEvE6InvokeIRKNS_7WeakPtrIS4_EEJRKbEEEvS6_OT_DpOT0_ #26 0x2b034eb86ddf _ZN4base8internal12InvokeHelperILb1EvE8MakeItSoIRKMN5blink9scheduler16TaskQueueManagerEFvbERKNS_7WeakPtrIS6_EEJRKbEEEvOT_OT0_DpOT1_ #27 0x2b034eb86d53 _ZN4base8internal7InvokerINS0_9BindStateIMN5blink9scheduler16TaskQueueManagerEFvbEJNS_7WeakPtrIS5_EEbEEEFvvEE7RunImplIRKS7_RKSt5tupleIJS9_bEEJLm0ELm1EEEEvOT_OT0_NS_13IndexSequenceIJXspT1_EEEE #28 0x2b034eb86c6c _ZN4base8internal7InvokerINS0_9BindStateIMN5blink9scheduler16TaskQueueManagerEFvbEJNS_7WeakPtrIS5_EEbEEEFvvEE3RunEPNS0_13BindStateBaseE #29 0x2b033ee9afee _ZNO4base8CallbackIFvvELNS_8internal8CopyModeE0ELNS2_10RepeatModeE0EE3RunEv #30 0x2b033ee9a72e base::debug::TaskAnnotator::RunTask() #31 0x2b033ef2525d base::MessageLoop::RunTask() #32 0x2b033ef254e4 base::MessageLoop::DeferOrRunPendingTask() #33 0x2b033ef257d4 base::MessageLoop::DoWork() #34 0x2b033ef3c8e8 base::MessagePumpDefault::Run() #35 0x2b033ef24df7 base::MessageLoop::RunHandler() #36 0x2b033efd049a base::RunLoop::Run() #37 0x2b0340c9c0e7 IPC::SyncChannel::WaitForReplyWithNestedMessageLoop() #38 0x2b0340c9c01f IPC::SyncChannel::WaitForReply() #39 0x2b0340c9b924 IPC::SyncChannel::Send() #40 0x2b0342d70877 content::ChildThreadImpl::Send() #41 0x2b0344d917ea content::RenderThreadImpl::Send() #42 0x2b0344d1768f content::RenderFrameImpl::Send() #43 0x2b0342d1d642 content::RenderFrameObserver::Send() #44 0x2b033b5852b8 printing::PrintWebViewHelper::RequestPrintPreview() #45 0x2b033b584daf printing::PrintWebViewHelper::ScriptedPrint() #46 0x2b0344d1763b content::RenderViewImpl::printPage() #48 0x2b034f62a519 blink::ChromeClientImpl::printDelegate() #49 0x2b035879291d blink::ChromeClient::print() #50 0x2b0357f4d6ec blink::LocalDOMWindow::print() #51 0x2b0358ed9219 blink::DOMWindowV8Internal::printMethod() #52 0x2b0358ed91aa blink::V8Window::printMethodCallback() #53 0x2b034d79b043 v8::internal::FunctionCallbackArguments::Call() #54 0x2b034d8eb40f v8::internal::(anonymous namespace)::HandleApiCallHelper<>() #55 0x2b034d8e9cc7 v8::internal::Builtin_Impl_HandleApiCall() #56 0x18c5c7684264 <unknown> r8: 00007ffeba14ba58 r9: 0000000000000000 r10: 00000000000000ff r11: 0000000003599588 r12: 0000000000000000 r13: 00007ffeba151128 r14: 00002858e8ef3020 r15: 00002b0358ed9170 di: 0000000000000000 si: 0000000000000000 bp: 00007ffeba14b880 bx: 00007ffeba1510a0 dx: 0000000000000000 ax: 0000000000000000 cx: 00002858e9006e20 sp: 00007ffeba14b880 ip: 00002b034f770c49 efl: 0000000000010246 cgf: 0000000000000033 erf: 0000000000000006 trp: 000000000000000e msk: 0000000000000000 cr2: 0000000000000080 [end of stack trace]
,
Apr 11 2017
,
Apr 12 2017
The GetFrame() call at the beginning of WebRemoteFrameImpl::DidStopLoading() returns a nullptr. Looks like that was originally from r187324, but nasko's status currently says away, so punting to creis to take a look. BTW, RequestPrintPreview() is doing a nested message loop, so beware. I also tried this in Firefox and it doesn't bother trying to print during onunload. IE/Edge don't seem to understand data: URLs?
,
Apr 12 2017
Thanks. lfg@, could you or dcheng@ take a look at this? FWIW, I'm ok with Firefox's approach of not printing during unload. thestig@, could you check the revision link in comment 3? I think it might be pointing to the wrong CL.
,
Apr 12 2017
,
Apr 12 2017
Yes, ignoring print() on unload seems reasonable to me, and is something we've talked about doing in the past as well.
,
Apr 12 2017
Yes, ignoring print() on unload seems reasonable to me, and is something we've talked about doing in the past as well.
,
Apr 26 2017
I've looked in to the crash, and it's a renderer crash in a cross-process transfer, which happens inside the printing nested message loop. Since the previous frame never committed the navigation (because we still are in the unload handler), we can't start processing messages from the browser process, because the renderer is in a bad state. I agree that blocking print() in the unload handlers seems like a reasonable fix, but there are several ways of accomplishing this: - Using LocalFrame::IsNavigationAllowed(), which relies on the FrameNavigationDisabler (which would allow printing as long as the frame can navigate). - Using PluginScriptForbiddenScope which is intended to fix similar issues with flash nested message loops (see https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/PluginScriptForbiddenScope.h?l=14). - Creating a new "PrintForbiddenScope" or similar. Should we also block printing in the beforeunload handler? I've looked into other browsers behavior, and Firefox does block printing both on the unload and beforeunload handlers. Is that a behavior we want to match? Edge, for instance, allows printing in both handlers (but it doesn't work when it's in the unload handler, the dialog that shows up is broken; it does work when printing from the beforeunload handler).
,
Apr 26 2017
Here's a test that reproduces the issue:
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, PrintOnUnloadHandler) {
ui_test_utils::NavigateToURL(
browser(), GURL(embedded_test_server()->GetURL("a.com", "/title1.html")));
content::WebContents* active_web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
// Create 2 iframes and navigate them to b.com.
EXPECT_TRUE(ExecuteScript(active_web_contents,
"var i = document.createElement('iframe'); i.id = "
"'child-0'; document.body.appendChild(i);"));
EXPECT_TRUE(ExecuteScript(active_web_contents,
"var i = document.createElement('iframe'); i.id = "
"'child-1'; document.body.appendChild(i);"));
EXPECT_TRUE(NavigateIframeToURL(
active_web_contents, "child-0",
GURL(embedded_test_server()->GetURL("b.com", "/title1.html"))));
EXPECT_TRUE(NavigateIframeToURL(
active_web_contents, "child-1",
GURL(embedded_test_server()->GetURL("b.com", "/title1.html"))));
content::RenderFrameHost* child_0 =
ChildFrameAt(active_web_contents->GetMainFrame(), 0);
content::RenderFrameHost* child_1 =
ChildFrameAt(active_web_contents->GetMainFrame(), 1);
// Add an unload handler that calls print() to child-0 iframe.
EXPECT_TRUE(ExecuteScript(
child_0, "document.body.onunload = function() { print(); }"));
// Transfer child-0 to a new process hosting c.com.
EXPECT_TRUE(NavigateIframeToURL(
active_web_contents, "child-0",
GURL(embedded_test_server()->GetURL("c.com", "/title1.html"))));
// Check that b.com's process is still alive.
bool renderer_alive = false;
EXPECT_TRUE(ExecuteScriptAndExtractBool(
child_1, "window.domAutomationController.send(true);", &renderer_alive));
EXPECT_TRUE(renderer_alive);
}
,
Apr 27 2017
Let's just match Firefox's behavior. That being said, why does the renderer end up in a bad state? Are there other nested message loops that can cause us to end up in this state? If so, simply blocking print() won't fix this. Maybe the IPC handler needs to be fixed to expect nested message loops and defer if necessary?
,
May 26 2017
For some reason the bot didn't pick up the change. Fix has landed a couple of days ago: https://codereview.chromium.org/2863203002/ |
||||||
►
Sign in to add a comment |
||||||
Comment 1 by arthurso...@chromium.org
, Mar 29 2017