New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 867274 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Aug 6
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 1
Type: Bug



Sign in to add a comment

race between FrameHostMsg_SwapOut_ACK and mojo pipe disconnect during cross-process navigation

Project Member Reported by caseq@google.com, Jul 25

Issue description

It looks like we have a race between FrameHostMsg_SwapOut_ACK and the renderer process disconnecting mojo pipes when exiting.

The problem reproduces nearly 100% on RenderFrameRedirectChain test in this WIP CL:
https://chromium-review.googlesource.com/c/chromium/src/+/1147741/3/headless/test/headless_protocol_browsertest.cc#355

Here's a summary of what happens:
- the test starts with one page, but immediately navigates to another, cross-origin, page with two subframes;
- the original page is the only page in the renderer, so when the navigation is committed and the original renderer receives FrameHostMsg_SwapOut, the process ref count goes to 0 and it starts shutting down;
- the RenderProcessHost of the original process receives RenderProcessHostImpl::ProcessDied() when the child process closes the mojo pipe;
- Since the original RenderFrameHost is still around, held by pending_delete_hosts_ in RenderFrameHostManager, it receives OnRenderProcessGone() from the RPH and invokes FrameTreeNode::ResetForNewProcess() which then cancels subframe navigations.

I think this was regressed by this change: https://chromium.googlesource.com/chromium/src/+/5c21f3ef93cfe2c7b7578e9726ff3f730db77037
... as we started to delay swapout ack, which now does not get to the browser in the above scenario.


 
Thanks for filing!  I'll take a look.  An easy fix might be to guard ResetForNewProcess() in RenderFrameHostImpl::OnRenderProcessGone() with "if (!is_active())", since a pending delete RFH should never be destroying the current RFH's children.  (Note that later on, OnRenderProcessGone() already checks is_active() and dispatches the swapout ACK.)  Seems like this bug might also occur if the pending delete RFH's process crashed after the new navigation committed, but before it completed running its unload handler, even independent of my change.

We're also investigating crashes likely related to the same change in issue 794625 -- I'll think about whether the explanation here might help determine how we get to crashes in that issue.
Components: Internals>Sandbox>SiteIsolation
Labels: OS-Android OS-Chrome OS-Linux OS-Mac OS-Windows
Here's a repro for OnRenderProcessGone() on the pending delete RFH incorrectly triggering ResetForNewProcess.  This should work even without r571625:

1. Increase RenderViewHostImpl::kUnloadTimeoutMS to 10000 (makes it much easier to repro)
2. Go to http://alexmos17.github.io/
3. From devtools execute:
   window.open();
4. Go back to first tab and execute
   window.onunload = () => { while(1); }
5. Navigate first tab to http://csreis.github.io/tests/cross-site-iframe-simple.html
6. Within the next 10 seconds, kill the blank second tab in task manager.

Notice that the kill incorrectly blanked out the subframe on the new page, which had nothing to do with the killed process.

Status: Started (was: Assigned)
Fix for the ResetForNewProcess side of things is up at https://chromium-review.googlesource.com/c/chromium/src/+/1150414.  I'll also need to separately investigate why process shutdown is happening before the swapout ACK is sent, and whether that means other things scheduled from unload handlers, like postMessage, might also be lost.
Project Member

Comment 4 by bugdroid1@chromium.org, Jul 25

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/d0d0eb02ab81d4da67eb57a11631f023e666e7bf

commit d0d0eb02ab81d4da67eb57a11631f023e666e7bf
Author: Alex Moshchuk <alexmos@chromium.org>
Date: Wed Jul 25 21:41:35 2018

When a RFH's process dies, only reset children if this is the current RFH.

Currently, RFHI::OnRenderProcessGone unconditionally calls
FTN::ResetForNewProcess().  This is not correct if the RFH that lost
the process is not the current one (i.e., pending deletion or
speculative), as in that case it will destroy the subframes on the
current page.  Fix this by only doing ResetForNewProcess() for current
RenderFrameHosts.

Bug:  867274 
Change-Id: I565825d7f813b97feaf4dd3559e9a8d8fafa5c1c
Reviewed-on: https://chromium-review.googlesource.com/1150414
Reviewed-by: Charlie Reis <creis@chromium.org>
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#578074}
[modify] https://crrev.com/d0d0eb02ab81d4da67eb57a11631f023e666e7bf/content/browser/frame_host/render_frame_host_impl.cc
[modify] https://crrev.com/d0d0eb02ab81d4da67eb57a11631f023e666e7bf/content/browser/frame_host/render_frame_host_impl.h
[modify] https://crrev.com/d0d0eb02ab81d4da67eb57a11631f023e666e7bf/content/browser/frame_host/render_frame_host_manager_browsertest.cc

Project Member

Comment 5 by bugdroid1@chromium.org, Aug 3

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/7ef6f71be74d68e3ccf8da2712003edb53316066

commit 7ef6f71be74d68e3ccf8da2712003edb53316066
Author: Alex Moshchuk <alexmos@chromium.org>
Date: Fri Aug 03 17:06:31 2018

Only release the process after sending the SwapOut ACK.

Previously, if the last active frame in a renderer process was going
away, it was possible to send out a process shutdown request (see
RenderProcessHostImpl::ShutdownRequest()) prior to actually sending
the swapout ACK, and potentially even prior to finishing tasks posted
from the unload handler, such as postMessages.  This CL postpones the
process release until after the swapout ACK has been sent.  As part of
this, it slightly refactors process refcounting for swapped out
transitions to happen in RenderFrameImpl rather than RenderWidget.
This is because when the swapout ACK is sent from a PostTask, the
widget that had been swapped out might've been destroyed, but we still
want the process to be released.

Bug: 794625,  867274 
Change-Id: I76b492461ce5a9317e71e184118ee02057143565
Reviewed-on: https://chromium-review.googlesource.com/1157530
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
Reviewed-by: Charlie Reis <creis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580576}
[modify] https://crrev.com/7ef6f71be74d68e3ccf8da2712003edb53316066/content/browser/frame_host/render_frame_host_impl.h
[modify] https://crrev.com/7ef6f71be74d68e3ccf8da2712003edb53316066/content/browser/site_per_process_browsertest.cc
[modify] https://crrev.com/7ef6f71be74d68e3ccf8da2712003edb53316066/content/renderer/render_frame_impl.cc
[modify] https://crrev.com/7ef6f71be74d68e3ccf8da2712003edb53316066/content/renderer/render_widget.cc
[modify] https://crrev.com/7ef6f71be74d68e3ccf8da2712003edb53316066/content/renderer/render_widget.h

Status: Fixed (was: Started)
Project Member

Comment 7 by bugdroid1@chromium.org, Aug 6

Labels: merge-merged-3497
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/b4a64e4cd81b7c0dad8b45043a5cef7903be4c38

commit b4a64e4cd81b7c0dad8b45043a5cef7903be4c38
Author: Alex Moshchuk <alexmos@chromium.org>
Date: Mon Aug 06 18:45:48 2018

Only release the process after sending the SwapOut ACK (Merge to M69)

Previously, if the last active frame in a renderer process was going
away, it was possible to send out a process shutdown request (see
RenderProcessHostImpl::ShutdownRequest()) prior to actually sending
the swapout ACK, and potentially even prior to finishing tasks posted
from the unload handler, such as postMessages.  This CL postpones the
process release until after the swapout ACK has been sent.  As part of
this, it slightly refactors process refcounting for swapped out
transitions to happen in RenderFrameImpl rather than RenderWidget.
This is because when the swapout ACK is sent from a PostTask, the
widget that had been swapped out might've been destroyed, but we still
want the process to be released.

TBR=alexmos@chromium.org

(cherry picked from commit 7ef6f71be74d68e3ccf8da2712003edb53316066)

Bug: 794625,  867274 
Change-Id: I76b492461ce5a9317e71e184118ee02057143565
Reviewed-on: https://chromium-review.googlesource.com/1157530
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
Reviewed-by: Charlie Reis <creis@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#580576}
Reviewed-on: https://chromium-review.googlesource.com/1163990
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Cr-Commit-Position: refs/branch-heads/3497@{#425}
Cr-Branched-From: 271eaf50594eb818c9295dc78d364aea18c82ea8-refs/heads/master@{#576753}
[modify] https://crrev.com/b4a64e4cd81b7c0dad8b45043a5cef7903be4c38/content/browser/frame_host/render_frame_host_impl.h
[modify] https://crrev.com/b4a64e4cd81b7c0dad8b45043a5cef7903be4c38/content/browser/site_per_process_browsertest.cc
[modify] https://crrev.com/b4a64e4cd81b7c0dad8b45043a5cef7903be4c38/content/renderer/render_frame_impl.cc
[modify] https://crrev.com/b4a64e4cd81b7c0dad8b45043a5cef7903be4c38/content/renderer/render_widget.cc
[modify] https://crrev.com/b4a64e4cd81b7c0dad8b45043a5cef7903be4c38/content/renderer/render_widget.h

Sign in to add a comment