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

Issue 802278 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Jan 2018
Cc:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 2
Type: Bug

Blocking:
issue 718489



Sign in to add a comment

Leak of RenderViewHostImpl (and consequently RenderProcessHostImpl) when GuestView set as opener

Project Member Reported by lukasza@chromium.org, Jan 16 2018

Issue description

Note: this is a follow-up to a memory leak discovered and discussed in  https://crbug.com/718489#c30  - #c38.


RenderFrameProxyHost can be constructed with a null |render_view_host| argument.  RenderFrameProxyHost's constructor used to have a CHECK that |render_view_host| argument is never null, but this has changed in r336565 (e.g. see https://codereview.chromium.org/972313002/patch/1060001/1070020).  An example of a callstack that constructs RenderFrameProxyHost with a null |render_view_host| argument:

  1 content::RenderFrameProxyHost::RenderFrameProxyHost(...) ../../content/browser/frame_host/render_frame_proxy_host.cc:68:35
  2 content::RenderFrameHostManager::CreateRenderFrameProxyHost(...) ../../content/browser/frame_host/render_frame_host_manager.cc:817:11
  3 content::RenderFrameHostManager::CreateOuterDelegateProxy(...) ../../content/browser/frame_host/render_frame_host_manager.cc:1744:7
  4 content::WebContentsImpl::AttachToOuterWebContentsFrame(...) ../../content/browser/web_contents/web_contents_impl.cc:1628:19
  5 guest_view::GuestViewMessageFilter::OnAttachToEmbedderFrame(...) ../../components/guest_view/browser/guest_view_message_filter.cc:174:23

When 2 GuestViews have the same storage partition, they are able to look each other up via window.open (see also  issue 794079 ).  Looking another frame via window.open needs to set the frame's opener (to the frame initiating the lookup).  This can lead to the following callstack:

  1 RenderProcessHostImpl::AddRoute(...) ../../content/browser/renderer_host/render_process_host_impl.cc:2207:33
  2 RenderWidgetHostImpl::RenderWidgetHostImpl(...) ../../content/browser/renderer_host/render_widget_host_impl.cc:371:13
  3 RenderWidgetHostFactory::Create(...) ../../content/browser/renderer_host/render_widget_host_factory.cc:25:14
  4 RenderViewHostFactory::Create(...) ../../content/browser/renderer_host/render_view_host_factory.cc:53:24
  5 FrameTree::CreateRenderViewHost(...) ../../content/browser/frame_host/frame_tree.cc:360:40
  6 RenderFrameHostManager::CreateRenderFrameProxy(...) ../../content/browser/frame_host/render_frame_host_manager.cc:1670:56
  7 FrameTree::CreateProxiesForSiteInstance(...) ../../content/browser/frame_host/frame_tree.cc:253:33
  8 RenderFrameHostManager::CreateOpenerProxies(...) ../../content/browser/frame_host/render_frame_host_manager.cc:2226:0
  9 RenderFrameProxyHost::UpdateOpener() ../../content/browser/frame_host/render_frame_proxy_host.cc:216:51
 10 RenderFrameHostManager::DidChangeOpener(...) ../../content/browser/frame_host/render_frame_host_manager.cc:299:18

The problem is that FrameHostManager::CreateRenderFrameProxy will create and leak a RenderViewHost:

  1666  int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) {
  ...
  1672    RenderViewHostImpl* render_view_host = nullptr;
  1673  
  1674    // Ensure a RenderViewHost exists for |instance|, as it creates the page
  1675    // level structure in Blink.
  1676    render_view_host =
  1677        frame_tree_node_->frame_tree()->GetRenderViewHost(instance);
  1678    if (!render_view_host) {
  1679      CHECK(frame_tree_node_->IsMainFrame());
  1680      render_view_host = frame_tree_node_->frame_tree()->CreateRenderViewHost(
  1681          instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, true, true);
  1682    }
  1683  
  1684    RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
  1685    if (proxy && proxy->is_render_frame_proxy_live())
  1686      return proxy->GetRoutingID();
  ...

If a |proxy| for |instance| already exists, but doesn't have an associated |render_view_host|, then on line 1678 we will realize that there is no |render_view_host| for |instance| (which is okay), but then we will incorrectly create a |render_view_host| on line 1680 - this RenderViewHostImpl will be leaked.  Normally a newly created RenderViewHostImpl is associated either with RenderFrameHostImpl or RenderFrameProxyHost - constructors of RFHI and RFPH call FrameTree::AddRenderViewHostRef and their destructors FrameTree::AddRenderViewHostRef call FrameTree::ReleaseRenderViewHostRef (which eventually will destroy the RenderViewHostImpl).  In this case, the newly created RenderViewHostImpl is forgotten, because lines 1684-1686 return an already existing, perfectly good RenderFrameProxyHost (which was legitimately created earlier *without* an associated RenderViewHostImpl).

Leaking of RenderViewHostImpl consequently leads to leaking of RenderProcessHostImpl (and leaking of a renderer process).
 
Project Member

Comment 1 by bugdroid1@chromium.org, Jan 17 2018

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

commit 4858e319b8fdedad532443b9e23a02fdd726f8fa
Author: Lukasz Anforowicz <lukasza@chromium.org>
Date: Wed Jan 17 06:42:39 2018

Don't leak a renderer process when guestview is set as window.opener.

RenderViewHostImpl will be leaked, unless it will be associated
with either a RenderFrameHostImpl or RenderFrameProxyHost (which
maintain RVHI's ref count by calling FrameTree::AddRenderViewHostRef
from their constructors and FrameTree::ReleaseRenderViewHostRef from
their destructors).  Leaking a RenderViewHostImpl leads to leaking
a renderer process.

This CL makes sure that such leak doesn't happen when a guestview is set
as window.opener (in this case a RenderFrameProxyHost exists without an
associated RenderViewHostImpl - we should not create (and leak) a
RenderViewHostImpl in this case).

This CL adds a test that accidentally found the leak of the renderer
process - this test will act as a regression test for the leak.  The
main purpose of the new test though is to act as a regression test
for findability of guestviews that share the same storage partition.

Bug:  802278 ,  794079 
Change-Id: Ibcac8952328b290050f66f4b82d3376b6001c757
Reviewed-on: https://chromium-review.googlesource.com/868631
Commit-Queue: Ɓukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: Nasko Oskov <nasko@chromium.org>
Reviewed-by: Lucas Gadani <lfg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#529653}
[modify] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/browser/apps/guest_view/web_view_browsertest.cc
[modify] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/dom_storage_isolation/page.html
[rename] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/dom_storage_isolation/page.js
[add] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/findability_isolation/main.js
[add] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/findability_isolation/manifest.json
[add] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/findability_isolation/message.js
[add] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/findability_isolation/message_titles.js
[add] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/findability_isolation/page.html
[add] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/findability_isolation/page.js
[add] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/findability_isolation/testing.js
[add] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/findability_isolation/tests.js
[add] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/chrome/test/data/extensions/platform_apps/web_view/findability_isolation/window.html
[modify] https://crrev.com/4858e319b8fdedad532443b9e23a02fdd726f8fa/content/browser/frame_host/render_frame_host_manager.cc

Status: Fixed (was: Untriaged)

Sign in to add a comment