Race between creating and showing widgets with same routing IDs from OOPIFs in different processes |
||
Issue description
Currently, WebContentsImpl tracks pending widgets (widgets that are created but not yet shown) in the pending_widget_views_ map, which is keyed by the new widget's routing_id only. Similarly, pending WebContents are tracked in pending_contents_, also keyed by a single routing_id. This is prone to a race when two OOPIFs in different processes create new widgets, and the two widgets happen to use the same routing ID, colliding in one of these maps. It seems that both of these maps should be keyed by (process_id, routing_id).
Here's a short test that illustrates the problem with pending WebContents:
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
TwoSubframesCreateWidgetsSimultaneously) {
GURL main_url(embedded_test_server()->GetURL(
"a.com", "/cross_site_iframe_factory.html?a(b,c)"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
FrameTreeNode* root = web_contents()->GetFrameTree()->root();
FrameTreeNode* child1 = root->child_at(0);
FrameTreeNode* child2 = root->child_at(1);
EXPECT_TRUE(ExecuteScript(child1->current_frame_host(),
"setTimeout(function() { window.open() }, 0)"));
EXPECT_TRUE(ExecuteScript(child2->current_frame_host(),
"setTimeout(function() { window.open() }, 0)"));
}
This is flaky, but it does hit the problem about 50% of the time for me, resulting in this crash:
[68575:68592:0516/143925:2753909165691:FATAL:resource_scheduler.cc(777)] Check failed: client_map_.empty().
#0 0x7f7c981e781e base::debug::StackTrace::StackTrace()
#1 0x7f7c9824a05f logging::LogMessage::~LogMessage()
#2 0x7f7c953efdc9 content::ResourceScheduler::~ResourceScheduler()
#3 0x7f7c953d404b std::default_delete<>::operator()()
#4 0x7f7c953c2e9c std::unique_ptr<>::reset()
#5 0x7f7c953b4422 content::ResourceDispatcherHostImpl::OnShutdown()
#6 0x7f7c9454be50 _ZN4base8internal15RunnableAdapterIMN7content17GpuWatchdogThreadEFvvEE3RunIPS3_JEEEvOT_DpOT0_
#7 0x7f7c953cc609 _ZN4base8internal12InvokeHelperILb0EvNS0_15RunnableAdapterIMN7content26ResourceDispatcherHostImplEFvvEEEE8MakeItSoIJPS4_EEEvS7_DpOT_
#8 0x7f7c953cc5cd _ZN4base8internal7InvokerINS_13IndexSequenceIJLm0EEEENS0_9BindStateINS0_15RunnableAdapterIMN7content26ResourceDispatcherHostImplEFvvEEEFvPS7_EJNS0_17UnretainedWrapperIS7_EEEEENS0_12InvokeHelperILb0EvSA_EEFvvEE3RunEPNS0_13BindStateBaseE
#9 0x7f7c981c79ee base::Callback<>::Run()
#10 0x7f7c981ed26e base::debug::TaskAnnotator::RunTask()
#11 0x7f7c9826781c base::MessageLoop::RunTask()
#12 0x7f7c98267ab8 base::MessageLoop::DeferOrRunPendingTask()
#13 0x7f7c98267d12 base::MessageLoop::DoWork()
#14 0x7f7c98281bfe base::MessagePumpLibevent::Run()
#15 0x7f7c9826720f base::MessageLoop::RunHandler()
#16 0x7f7c9830ffb4 base::RunLoop::Run()
#17 0x7f7c98266284 base::MessageLoop::Run()
#18 0x7f7c983a73a9 base::Thread::Run()
#19 0x7f7c94edac66 content::BrowserThreadImpl::IOThreadRun()
#20 0x7f7c94edb00e content::BrowserThreadImpl::Run()
#21 0x7f7c983a76f9 base::Thread::ThreadMain()
#22 0x7f7c983928ba base::(anonymous namespace)::ThreadFunc()
In the problematic runs, the sequence of calls is:
CreateNewWindow: process_id=4 routing_id=6
CreateNewWindow: process_id=5 routing_id=6
ShowCreatedWindow: routing_id=6
ShowCreatedWindow: routing_id=6
I don't think this is blocking launch, as I believe all operations triggering these new widgets require a user gesture (clicking on a <select> menu, clicking on a link to open a popup, fullscreening Flash), so the probability of this happening in practice is very low. I'll assign to myself for now, since I already have drafts for a test and half of the fix.
,
May 16 2016
Since these maps are kept per-WebContents, I don't think it's possible to get a conflict unless two widgets are created from different processes which both belong to the same WebContents. It's not possible to get two processes for the same WebContents outside of OOPIF modes, is it?
,
May 16 2016
Ah, good point. Yes, should be OOPIF-specific.
,
May 23 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/c2a8cec37a56e92d29d91b936734cd1e5ee28734 commit c2a8cec37a56e92d29d91b936734cd1e5ee28734 Author: alexmos <alexmos@chromium.org> Date: Mon May 23 22:19:53 2016 Track pending WebContents and widgets by (process_id, routing_id) pair. Currently, WebContentsImpl tracks pending widgets (widgets that are created but not yet shown) in the pending_widget_views_ map, which is keyed by the new widget's routing_id only. Similarly, pending WebContents are tracked in pending_contents_, also keyed by a single routing_id. This is prone to a race when two OOPIFs in different processes (but part of the same WebContents) create new widgets, and the two widgets happen to use the same routing ID, colliding in one of these maps. This CL changes both of these maps to be keyed by (process_id, routing_id). BUG= 612276 , 593522 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_site_isolation Review-Url: https://codereview.chromium.org/1986643002 Cr-Commit-Position: refs/heads/master@{#395435} [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/browser/browser_plugin/browser_plugin_guest.cc [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/browser/frame_host/interstitial_page_impl.cc [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/browser/frame_host/interstitial_page_impl.h [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/browser/renderer_host/render_view_host_delegate.h [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/browser/renderer_host/render_view_host_impl.cc [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/browser/site_per_process_browsertest.cc [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/browser/web_contents/web_contents_impl.cc [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/browser/web_contents/web_contents_impl.h [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/browser/web_contents/web_contents_impl_unittest.cc [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/test/data/site_isolation/page-with-select.html [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/test/test_web_contents.cc [modify] https://crrev.com/c2a8cec37a56e92d29d91b936734cd1e5ee28734/content/test/test_web_contents.h
,
May 27 2016
|
||
►
Sign in to add a comment |
||
Comment 1 by creis@chromium.org
, May 16 2016