Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Side by Side Diff: content/browser/site_per_process_browsertest.cc

Issue 2410153005: Fix RenderView reuse issues when canceling a pending RenderFrameHost. (Closed)
Patch Set: Rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/site_per_process_browsertest.h" 5 #include "content/browser/site_per_process_browsertest.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 8361 matching lines...) Expand 10 before | Expand all | Expand 10 after
8372 // Navigate the iframe cross-site. 8372 // Navigate the iframe cross-site.
8373 NavigationHandleWatcher watcher(shell()->web_contents()); 8373 NavigationHandleWatcher watcher(shell()->web_contents());
8374 TestNavigationObserver load_observer(shell()->web_contents()); 8374 TestNavigationObserver load_observer(shell()->web_contents());
8375 GURL frame_url = embedded_test_server()->GetURL("c.com", "/title1.html"); 8375 GURL frame_url = embedded_test_server()->GetURL("c.com", "/title1.html");
8376 EXPECT_TRUE(ExecuteScript( 8376 EXPECT_TRUE(ExecuteScript(
8377 shell()->web_contents(), 8377 shell()->web_contents(),
8378 "window.frames[0].location = \"" + frame_url.spec() + "\";")); 8378 "window.frames[0].location = \"" + frame_url.spec() + "\";"));
8379 load_observer.Wait(); 8379 load_observer.Wait();
8380 } 8380 }
8381 8381
8382 // Test that when canceling a pending RenderFrameHost in the middle of a
8383 // redirect, and then killing the corresponding RenderView's renderer process,
8384 // the RenderViewHost isn't reused in an improper state later. Previously this
8385 // led to a crash in CreateRenderView when recreating the RenderView due to a
8386 // stale main frame routing ID. See https://crbug.com/627400.
8387 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
8388 ReuseNonLiveRenderViewHostAfterCancelPending) {
8389 GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
8390 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
8391 GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html"));
8392
8393 EXPECT_TRUE(NavigateToURL(shell(), a_url));
8394
8395 // Open a popup and navigate it to b.com.
8396 Shell* popup = OpenPopup(shell(), a_url, "popup");
8397 EXPECT_TRUE(NavigateToURL(popup, b_url));
8398
8399 // Open a second popup and navigate it to b.com, which redirects to c.com.
8400 // The navigation to b.com will create a pending RenderFrameHost, which will
8401 // be canceled during the redirect to c.com. Note that NavigateToURL will
8402 // return false because the committed URL won't match the requested URL due
8403 // to the redirect.
8404 Shell* popup2 = OpenPopup(shell(), a_url, "popup2");
8405 TestNavigationObserver observer(popup2->web_contents());
8406 GURL redirect_url(embedded_test_server()->GetURL(
8407 "b.com", "/server-redirect?" + c_url.spec()));
8408 EXPECT_FALSE(NavigateToURL(popup2, redirect_url));
8409 EXPECT_EQ(c_url, observer.last_navigation_url());
8410 EXPECT_TRUE(observer.last_navigation_succeeded());
8411
8412 // Kill the b.com process (which currently hosts a RenderFrameProxy that
8413 // replaced the pending RenderFrame in |popup2|, as well as the RenderFrame
8414 // for |popup|).
8415 RenderProcessHost* b_process =
8416 popup->web_contents()->GetMainFrame()->GetProcess();
8417 RenderProcessHostWatcher crash_observer(
8418 b_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
8419 b_process->Shutdown(0, false);
8420 crash_observer.Wait();
8421
8422 // Navigate the second popup to b.com. This used to crash when creating the
8423 // RenderView, because it reused the RenderViewHost created by the canceled
8424 // navigation to b.com, and that RenderViewHost had a stale main frame
8425 // routing ID and active state.
8426 EXPECT_TRUE(NavigateToURL(popup2, b_url));
8427 }
8428
8429 // Check that after a pending RFH is canceled and replaced with a proxy (which
8430 // reuses the canceled RFH's RenderViewHost), navigating to a main frame in the
8431 // same site as the canceled RFH doesn't lead to a renderer crash. The steps
8432 // here are similar to ReuseNonLiveRenderViewHostAfterCancelPending, but don't
8433 // involve crashing the renderer. See https://crbug.com/651980.
8434 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
8435 RecreateMainFrameAfterCancelPending) {
8436 GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
8437 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
8438 GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html"));
8439
8440 EXPECT_TRUE(NavigateToURL(shell(), a_url));
8441
8442 // Open a popup and navigate it to b.com.
8443 Shell* popup = OpenPopup(shell(), a_url, "popup");
8444 EXPECT_TRUE(NavigateToURL(popup, b_url));
8445
8446 // Open a second popup and navigate it to b.com, which redirects to c.com.
8447 // The navigation to b.com will create a pending RenderFrameHost, which will
8448 // be canceled during the redirect to c.com. Note that NavigateToURL will
8449 // return false because the committed URL won't match the requested URL due
8450 // to the redirect.
8451 Shell* popup2 = OpenPopup(shell(), a_url, "popup2");
8452 TestNavigationObserver observer(popup2->web_contents());
8453 GURL redirect_url(embedded_test_server()->GetURL(
8454 "b.com", "/server-redirect?" + c_url.spec()));
8455 EXPECT_FALSE(NavigateToURL(popup2, redirect_url));
8456 EXPECT_EQ(c_url, observer.last_navigation_url());
8457 EXPECT_TRUE(observer.last_navigation_succeeded());
8458
8459 // Navigate the second popup to b.com. This used to crash the b.com renderer
8460 // because it failed to delete the canceled RFH's RenderFrame, so this caused
8461 // it to try to create a frame widget which already existed.
8462 EXPECT_TRUE(NavigateToURL(popup2, b_url));
8463 }
8464
8465 // Check that when a pending RFH is canceled and a proxy needs to be created in
8466 // its place, the proxy is properly initialized on the renderer side. See
8467 // https://crbug.com/653746.
8468 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
8469 CommunicateWithProxyAfterCancelPending) {
8470 GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
8471 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
8472 GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html"));
8473
8474 EXPECT_TRUE(NavigateToURL(shell(), a_url));
8475
8476 // Open a popup and navigate it to b.com.
8477 Shell* popup = OpenPopup(shell(), a_url, "popup");
8478 EXPECT_TRUE(NavigateToURL(popup, b_url));
8479
8480 // Open a second popup and navigate it to b.com, which redirects to c.com.
8481 // The navigation to b.com will create a pending RenderFrameHost, which will
8482 // be canceled during the redirect to c.com. Note that NavigateToURL will
8483 // return false because the committed URL won't match the requested URL due
8484 // to the redirect.
8485 Shell* popup2 = OpenPopup(shell(), a_url, "popup2");
8486 TestNavigationObserver observer(popup2->web_contents());
8487 GURL redirect_url(embedded_test_server()->GetURL(
8488 "b.com", "/server-redirect?" + c_url.spec()));
8489 EXPECT_FALSE(NavigateToURL(popup2, redirect_url));
8490 EXPECT_EQ(c_url, observer.last_navigation_url());
8491 EXPECT_TRUE(observer.last_navigation_succeeded());
8492
8493 // Because b.com has other active frames (namely, the frame in |popup|),
8494 // there should be a proxy created for the canceled RFH, and it should be
8495 // live.
8496 SiteInstance* b_instance = popup->web_contents()->GetSiteInstance();
8497 FrameTreeNode* popup2_root =
8498 static_cast<WebContentsImpl*>(popup2->web_contents())
8499 ->GetFrameTree()
8500 ->root();
8501 RenderFrameProxyHost* proxy =
8502 popup2_root->render_manager()->GetRenderFrameProxyHost(b_instance);
8503 EXPECT_TRUE(proxy);
8504 EXPECT_TRUE(proxy->is_render_frame_proxy_live());
8505
8506 // Add a postMessage listener in |popup2| (currently at a c.com URL).
8507 EXPECT_TRUE(
8508 ExecuteScript(popup2,
8509 "window.addEventListener('message', function(event) {\n"
8510 " document.title=event.data;\n"
8511 "});"));
8512
8513 // Check that a postMessage can be sent via |proxy| above. This needs to be
8514 // done from the b.com process. |popup| is currently in b.com, but it can't
8515 // reach the window reference for |popup2| due to a security restriction in
8516 // Blink. So, navigate the main tab to b.com and then send a postMessage to
8517 // |popup2|. This is allowed since the main tab is |popup2|'s opener.
8518 EXPECT_TRUE(NavigateToURL(shell(), b_url));
8519
8520 base::string16 expected_title(base::UTF8ToUTF16("foo"));
8521 TitleWatcher title_watcher(popup2->web_contents(), expected_title);
8522 EXPECT_TRUE(ExecuteScript(
8523 shell(), "window.open('','popup2').postMessage('foo', '*');"));
8524 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
8525 }
8526
8382 } // namespace content 8527 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_frame_host_manager.cc ('k') | content/renderer/render_frame_proxy.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698