race between FrameHostMsg_SwapOut_ACK and mojo pipe disconnect during cross-process navigation |
|||||
Issue descriptionIt 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.
,
Jul 25
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.
,
Jul 25
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.
,
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
,
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
,
Aug 6
,
Aug 6
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 |
|||||
Comment 1 by alex...@chromium.org
, Jul 25