From 9463868c8a2d30b6a81db9fd2b61e8a5935ac347 Mon Sep 17 00:00:00 2001 From: dcheng Date: Fri, 8 May 2015 12:30:20 -0700 Subject: [PATCH] Swap the main frame in --site-per-process mode too. Calling swap() is required to set up a lot of required state in Blink for the WebRemoteFrame. Without this, bad things happen. BUG=475003 Review URL: https://codereview.chromium.org/1106673002 Cr-Commit-Position: refs/heads/master@{#329012} --- content/browser/site_per_process_browsertest.cc | 38 +++++++++++++++++++++++++ content/renderer/render_frame_impl.cc | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index df9e55e8e8f6..aa410fa5abb4 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc @@ -2395,4 +2395,42 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, RFPHDestruction) { DepictFrameTree(root)); } +// Test that opening a cross-site window with child frames doesn't crash either +// renderer in --site-per-process. This was previously broken because frame +// swaps weren't being performed on main frames, so it would crash when trying +// to mirror the child frames. https://crbug.com/475003 +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + OpenCrossSiteWindowWithFrames) { + ASSERT_EQ(1u, Shell::windows().size()); + Shell* main_window = Shell::windows()[0]; + + // Navigate the main window. + GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html")); + NavigateToURL(main_window, main_url); + EXPECT_EQ(main_window->web_contents()->GetLastCommittedURL(), main_url); + + // Load a cross-site page into a new window. + GURL cross_url = + embedded_test_server()->GetURL("foo.com", "/site_per_process_main.html"); + std::string script = "window.open('" + cross_url.spec() + "')"; + EXPECT_TRUE(ExecuteScript(main_window->web_contents(), script)); + ASSERT_EQ(2u, Shell::windows().size()); + Shell* cross_window = Shell::windows()[1]; + WaitForLoadStop(cross_window->web_contents()); + EXPECT_EQ(cross_window->web_contents()->GetLastCommittedURL(), cross_url); + + // Make sure the main window is still live. To create a synchronization point + // and ensure that the renderer has processed all the messages for updating + // the frame tree, execute a simple bit of JS first. + EXPECT_TRUE(ExecuteScript(main_window->web_contents(), "true")); + EXPECT_TRUE(static_cast(main_window->web_contents()) + ->GetMainFrame() + ->IsRenderFrameLive()); + // And check the cross-site window too. + EXPECT_TRUE(ExecuteScript(cross_window->web_contents(), "true")); + EXPECT_TRUE(static_cast(cross_window->web_contents()) + ->GetMainFrame() + ->IsRenderFrameLive()); +} + } // namespace content diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index b44691dc57a9..ea6ade7da7b3 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -1227,7 +1227,7 @@ void RenderFrameImpl::OnSwapOut( // Now that all of the cleanup is complete and the browser side is notified, // start using the RenderFrameProxy, if one is created. if (proxy) { - if (!is_main_frame) { + if (!is_main_frame || is_site_per_process) { frame_->swap(proxy->web_frame()); if (is_loading) -- 2.11.4.GIT