Commit 7a87e4e8 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

mac: Fix WebContentsImpl::UpdateWebContentsVisibility calling RWHVMac

We encounter the following stack when destroying the RWHVMac
  RenderWidgetHostViewMac::Show
  WebContentsImpl::WasShown
  WebContentsImpl::UpdateWebContentsVisibility
  ...
  -[NSView removeFromSuperview]
  RenderWidgetHostViewNSViewBridgeLocal::~(dtor)
  RenderWidgetHostViewMac::Destroy

This is problematic, as WebContentsImpl::UpdateWebContentsVisibility
will make a bunch of calls on RenderWidgetHostViewMac that all assume
that we are not mid-tear-down.

To avoid this, make the call to -[NSView removeFromSuperview] be a
delayed callback. That way the call will happen after the RWHVMac has
been entirely destroyed, and UpdateWebContentsVisibility will no longer
have a RWHVMac to call back into.

Bug: 834931
Change-Id: I88412173b005dfdc26026db6b4c12b31e6541e7c
Reviewed-on: https://chromium-review.googlesource.com/1025396Reviewed-by: default avatarSidney San Martín <sdy@chromium.org>
Commit-Queue: ccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553941}
parent f10f8aa0
......@@ -97,7 +97,13 @@ RenderWidgetHostViewNSViewBridgeLocal::RenderWidgetHostViewNSViewBridgeLocal(
RenderWidgetHostViewNSViewBridgeLocal::
~RenderWidgetHostViewNSViewBridgeLocal() {
[cocoa_view_ setClientDisconnected];
[cocoa_view_ removeFromSuperview];
// Do not immediately remove |cocoa_view_| from the NSView heirarchy, because
// the call to -[NSView removeFromSuperview] may cause use to call into the
// RWHVMac during tear-down, via WebContentsImpl::UpdateWebContentsVisibility.
// https://crbug.com/834931
[cocoa_view_ performSelector:@selector(removeFromSuperview)
withObject:nil
afterDelay:0];
cocoa_view_.autorelease();
display::Screen::GetScreen()->RemoveObserver(this);
popup_window_.reset();
......
......@@ -227,11 +227,7 @@ void ExtractUnderlines(NSAttributedString* string,
}
- (void)dealloc {
if (responderDelegate_ &&
[responderDelegate_ respondsToSelector:@selector(viewGone:)])
[responderDelegate_ viewGone:self];
responderDelegate_.reset();
DCHECK([self clientIsDisconnected]);
[[NSNotificationCenter defaultCenter] removeObserver:self];
// Update and cache the new input context. Otherwise,
......@@ -375,6 +371,15 @@ void ExtractUnderlines(NSAttributedString* string,
- (void)setClientDisconnected {
client_ = noopClient_.get();
// |responderDelegate_| may attempt to access the RenderWidgetHostViewMac
// through its internal pointers, so detach it here.
// TODO(ccameron): Force |responderDelegate_| to use the |client_| as well,
// and the viewGone method to clientGone.
if (responderDelegate_ &&
[responderDelegate_ respondsToSelector:@selector(viewGone:)])
[responderDelegate_ viewGone:self];
responderDelegate_.reset();
}
- (bool)clientIsDisconnected {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment