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

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: Nits 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 8321 matching lines...) Expand 10 before | Expand all | Expand 10 after
8332 8332
8333 // Now have the cross-process navigation commit and mark the current RFH as 8333 // Now have the cross-process navigation commit and mark the current RFH as
8334 // pending deletion. 8334 // pending deletion.
8335 cross_site_manager.WaitForNavigationFinished(); 8335 cross_site_manager.WaitForNavigationFinished();
8336 8336
8337 // Resume the navigation in the previous RFH that has just been marked as 8337 // Resume the navigation in the previous RFH that has just been marked as
8338 // pending deletion. We should not crash. 8338 // pending deletion. We should not crash.
8339 transfer_manager.WaitForNavigationFinished(); 8339 transfer_manager.WaitForNavigationFinished();
8340 } 8340 }
8341 8341
8342 // Test that when canceling a pending RenderFrameHost in the middle of a
8343 // redirect, and then killing the corresponding RenderView's renderer process,
8344 // the RenderViewHost isn't reused in an improper state later. Previously this
8345 // led to a crash in CreateRenderView when recreating the RenderView due to a
8346 // stale main frame routing ID. See https://crbug.com/627400.
8347 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
8348 ReuseNonLiveRenderViewAfterCancelPending) {
8349 GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
8350 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
8351 GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html"));
8352
8353 EXPECT_TRUE(NavigateToURL(shell(), a_url));
8354
8355 // Open a popup and navigate it to b.com.
8356 Shell* popup = OpenPopup(shell(), a_url, "popup");
8357 EXPECT_TRUE(NavigateToURL(popup, b_url));
8358
8359 // Open a second popup and navigate it to b.com, which redirects to c.com.
8360 // The navigation to b.com will create a pending RenderFrameHost, which will
8361 // be canceled during the redirect to c.com. Note that NavigateToURL will
8362 // return false because the committed URL won't match the requested URL due
8363 // to the redirect.
8364 Shell* popup2 = OpenPopup(shell(), a_url, "popup2");
8365 TestNavigationObserver observer(popup2->web_contents());
8366 GURL redirect_url(embedded_test_server()->GetURL(
8367 "b.com", "/server-redirect?" + c_url.spec()));
8368 EXPECT_FALSE(NavigateToURL(popup2, redirect_url));
8369 EXPECT_EQ(c_url, observer.last_navigation_url());
8370 EXPECT_TRUE(observer.last_navigation_succeeded());
8371
8372 // Kill the b.com process (which currently hosts a RenderFrameProxy that
8373 // replaced the pending RenderFrame in |popup2|, as well as the RenderFrame
8374 // for |popup|).
8375 RenderProcessHost* b_process =
8376 popup->web_contents()->GetMainFrame()->GetProcess();
8377 RenderProcessHostWatcher crash_observer(
8378 b_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
8379 b_process->Shutdown(0, false);
8380 crash_observer.Wait();
8381
8382 // Navigate the second popup to b.com. This used to crash when creating the
8383 // RenderView, because it reused the RenderViewHost created by the canceled
8384 // navigation to b.com, and that RenderViewHost had a stale main frame
8385 // routing ID and active state.
8386 EXPECT_TRUE(NavigateToURL(popup2, b_url));
8387 }
8388
8389 // Check that after a pending RFH is canceled and replaced with a proxy (which
8390 // reuses the canceled RFH's RenderView), navigating to a main frame in the
nasko 2016/10/13 21:26:28 nit: RenderViewHost, since you mention RFH's.
alexmos 2016/10/14 17:07:38 Done.
8391 // same site as the canceled RFH doesn't lead to a renderer crash. The steps
8392 // here are similar to the test above, but don't involve crashing the renderer.
nasko 2016/10/13 21:26:28 nit: replace "test above" with the explicit name o
alexmos 2016/10/14 17:07:38 Done.
8393 // See https://crbug.com/651980.
8394 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
8395 RecreateMainFrameAfterCancelPending) {
8396 GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
8397 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
8398 GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html"));
8399
8400 EXPECT_TRUE(NavigateToURL(shell(), a_url));
8401
8402 // Open a popup and navigate it to b.com.
8403 Shell* popup = OpenPopup(shell(), a_url, "popup");
8404 EXPECT_TRUE(NavigateToURL(popup, b_url));
8405
8406 // Open a second popup and navigate it to b.com, which redirects to c.com.
8407 // The navigation to b.com will create a pending RenderFrameHost, which will
8408 // be canceled during the redirect to c.com. Note that NavigateToURL will
8409 // return false because the committed URL won't match the requested URL due
8410 // to the redirect.
8411 Shell* popup2 = OpenPopup(shell(), a_url, "popup2");
8412 TestNavigationObserver observer(popup2->web_contents());
8413 GURL redirect_url(embedded_test_server()->GetURL(
8414 "b.com", "/server-redirect?" + c_url.spec()));
8415 EXPECT_FALSE(NavigateToURL(popup2, redirect_url));
8416 EXPECT_EQ(c_url, observer.last_navigation_url());
8417 EXPECT_TRUE(observer.last_navigation_succeeded());
8418
8419 // Navigate the second popup to b.com. This used to crash the b.com renderer
8420 // because it failed to delete the canceled RFH's RenderFrame, so this caused
8421 // it to try to create a frame widget which already existed.
8422 EXPECT_TRUE(NavigateToURL(popup2, b_url));
8423 }
8424
8425 // Check that when a pending RFH is canceled and a proxy needs to be created in
8426 // its place, the proxy is properly initialized on the renderer side. See
8427 // https://crbug.com/653746.
8428 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
8429 CommunicateWithProxyAfterCancelPending) {
8430 GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
8431 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
8432 GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html"));
8433
8434 EXPECT_TRUE(NavigateToURL(shell(), a_url));
8435
8436 // Open a popup and navigate it to b.com.
8437 Shell* popup = OpenPopup(shell(), a_url, "popup");
8438 EXPECT_TRUE(NavigateToURL(popup, b_url));
8439
8440 // Open a second popup and navigate it to b.com, which redirects to c.com.
8441 // The navigation to b.com will create a pending RenderFrameHost, which will
8442 // be canceled during the redirect to c.com. Note that NavigateToURL will
8443 // return false because the committed URL won't match the requested URL due
8444 // to the redirect.
8445 Shell* popup2 = OpenPopup(shell(), a_url, "popup2");
8446 TestNavigationObserver observer(popup2->web_contents());
8447 GURL redirect_url(embedded_test_server()->GetURL(
8448 "b.com", "/server-redirect?" + c_url.spec()));
8449 EXPECT_FALSE(NavigateToURL(popup2, redirect_url));
8450 EXPECT_EQ(c_url, observer.last_navigation_url());
8451 EXPECT_TRUE(observer.last_navigation_succeeded());
8452
8453 // Because b.com has other active frames (namely, the frame in |popup|),
8454 // there should be a proxy created for the canceled RFH, and it should be
8455 // live.
8456 SiteInstance* b_instance = popup->web_contents()->GetSiteInstance();
8457 FrameTreeNode* popup2_root =
8458 static_cast<WebContentsImpl*>(popup2->web_contents())
8459 ->GetFrameTree()
8460 ->root();
8461 RenderFrameProxyHost* proxy =
8462 popup2_root->render_manager()->GetRenderFrameProxyHost(b_instance);
8463 EXPECT_TRUE(proxy);
8464 EXPECT_TRUE(proxy->is_render_frame_proxy_live());
8465
8466 // Add a postMessage listener in |popup2| (currently at a c.com URL).
8467 EXPECT_TRUE(
8468 ExecuteScript(popup2,
8469 "window.addEventListener('message', function(event) {\n"
8470 " document.title=event.data;\n"
8471 "});"));
8472
8473 // Check that a postMessage can be sent via |proxy| above. This needs to be
8474 // done from the b.com process. |popup| is currently in b.com, but it can't
8475 // reach the window reference for |popup2| due to a security restriction in
8476 // Blink. So, navigate the main tab to b.com and then send a postMessage to
8477 // |popup2|. This is allowed since the main tab is |popup2|'s opener.
8478 EXPECT_TRUE(NavigateToURL(shell(), b_url));
8479
8480 base::string16 expected_title(base::UTF8ToUTF16("foo"));
8481 TitleWatcher title_watcher(popup2->web_contents(), expected_title);
8482 EXPECT_TRUE(ExecuteScript(
8483 shell(), "window.open('','popup2').postMessage('foo', '*');"));
8484 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
8485 }
8486
8342 } // namespace content 8487 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698