diff options
author | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-10 21:19:58 +0000 |
---|---|---|
committer | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-10 21:19:58 +0000 |
commit | 8e53730a2199f914cbd79cf72c363ad33aea0802 (patch) | |
tree | 48b3d8d5f3ae6ebcafd2fe8444e5976592dcb125 | |
parent | 2248462eb24d976e2146aff311cccbc92352d0b4 (diff) | |
download | chromium_src-8e53730a2199f914cbd79cf72c363ad33aea0802.zip chromium_src-8e53730a2199f914cbd79cf72c363ad33aea0802.tar.gz chromium_src-8e53730a2199f914cbd79cf72c363ad33aea0802.tar.bz2 |
Fix a crash in linux if the renderer process dies too fast. On mac, we
just don't get the sad tab page.
If the renderer dies before it sends a ViewHostMsg_RenderViewReady message,
we never get the TAB_CONTENTS_CONNECTED, which in turn means that
TAB_CONTENTS_DISCONNECTED doesn't fire. If TAB_CONTENTS_DISCONNECTED
doesn't fire, we never initialize sad_tab_ in tab_contents_view_gtk.cc and
crash the browser process.
I found this crash on the crash server:
http://crash/reportdetail?
reportid=fb3a7bc60c67eb1e&product=Chrome_Linux&version=3.0.183.1&date=&signa
ture=TabContentsViewGtk::Invalidate()-534CC7
BUG=13715
Review URL: http://codereview.chromium.org/119395
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18087 0039d316-1c4b-4281-b951-d872f2087c98
8 files changed, 27 insertions, 35 deletions
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 4d200c2..ad09bf6 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -1537,9 +1537,8 @@ void TabContents::RenderViewGone(RenderViewHost* rvh) { NotifyDisconnected(); SetIsCrashed(true); - // Force an invalidation to render sad tab. The view will notice we crashed - // when it paints. - view_->Invalidate(); + // Tell the view that we've crashed so it can prepare the sad tab page. + view_->OnTabCrashed(); // Hide any visible hung renderer warning for this web contents' process. HungRendererDialog::HideForTabContents(AsWC(this)); diff --git a/chrome/browser/tab_contents/tab_contents_view.h b/chrome/browser/tab_contents/tab_contents_view.h index a7299f1..6acbb30 100644 --- a/chrome/browser/tab_contents/tab_contents_view.h +++ b/chrome/browser/tab_contents/tab_contents_view.h @@ -91,10 +91,9 @@ class TabContentsView : public RenderViewHostDelegate::View { // trying to find a specific window. virtual void SetPageTitle(const std::wstring& title) = 0; - // Schedules a complete repaint of the window. This is used for cases where - // the existing contents became invalid due to an external event, such as the - // renderer crashing. - virtual void Invalidate() = 0; + // Used to notify the view that a tab has crashed so each platform can + // prepare the sad tab. + virtual void OnTabCrashed() = 0; // TODO(brettw) this is a hack. It's used in two places at the time of this // writing: (1) when render view hosts switch, we need to size the replaced diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc index fd00d82..438e1af 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc @@ -105,8 +105,6 @@ TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) gtk_widget_show(fixed_.get()); registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED, Source<TabContents>(tab_contents)); - registrar_.Add(this, NotificationType::TAB_CONTENTS_DISCONNECTED, - Source<TabContents>(tab_contents)); } TabContentsViewGtk::~TabContentsViewGtk() { @@ -193,8 +191,12 @@ void TabContentsViewGtk::SetPageTitle(const std::wstring& title) { gdk_window_set_title(content_view->window, WideToUTF8(title).c_str()); } -void TabContentsViewGtk::Invalidate() { - gtk_widget_queue_draw(sad_tab_->widget()); +void TabContentsViewGtk::OnTabCrashed() { + if (!sad_tab_.get()) { + sad_tab_.reset(new SadTabGtk); + InsertIntoContentArea(sad_tab_->widget()); + gtk_widget_show(sad_tab_->widget()); + } } void TabContentsViewGtk::SizeContents(const gfx::Size& size) { @@ -273,12 +275,6 @@ void TabContentsViewGtk::Observe(NotificationType type, sad_tab_.reset(); break; } - case NotificationType::TAB_CONTENTS_DISCONNECTED: { - sad_tab_.reset(new SadTabGtk); - InsertIntoContentArea(sad_tab_->widget()); - gtk_widget_show(sad_tab_->widget()); - break; - } default: NOTREACHED() << "Got a notification we didn't register for."; break; diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h index b6908ff..72bcfe1 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.h +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h @@ -38,7 +38,7 @@ class TabContentsViewGtk : public TabContentsView, virtual void GetContainerBounds(gfx::Rect* out) const; virtual void OnContentsDestroy(); virtual void SetPageTitle(const std::wstring& title); - virtual void Invalidate(); + virtual void OnTabCrashed(); virtual void SizeContents(const gfx::Size& size); virtual void Focus(); virtual void SetInitialFocus(); diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.h b/chrome/browser/tab_contents/tab_contents_view_mac.h index 2745050..91af1a6 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.h +++ b/chrome/browser/tab_contents/tab_contents_view_mac.h @@ -48,7 +48,7 @@ class TabContentsViewMac : public TabContentsView, virtual void OnContentsDestroy(); virtual void RenderViewCreated(RenderViewHost* host); virtual void SetPageTitle(const std::wstring& title); - virtual void Invalidate(); + virtual void OnTabCrashed(); virtual void SizeContents(const gfx::Size& size); virtual void Focus(); virtual void SetInitialFocus(); diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm index 4cd0f57..fd32310 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.mm +++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm @@ -30,8 +30,6 @@ TabContentsViewMac::TabContentsViewMac(TabContents* tab_contents) : TabContentsView(tab_contents) { registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED, Source<TabContents>(tab_contents)); - registrar_.Add(this, NotificationType::TAB_CONTENTS_DISCONNECTED, - Source<TabContents>(tab_contents)); } TabContentsViewMac::~TabContentsViewMac() { @@ -102,8 +100,16 @@ void TabContentsViewMac::SetPageTitle(const std::wstring& title) { // Meaningless on the Mac; widgets don't have a "title" attribute } -void TabContentsViewMac::Invalidate() { - [cocoa_view_.get() setNeedsDisplay:YES]; +void TabContentsViewMac::OnTabCrashed() { + if (!sad_tab_.get()) { + SadTabView* view = [[SadTabView alloc] initWithFrame:NSZeroRect]; + sad_tab_.reset(view); + + // Set as the dominant child. + [cocoa_view_.get() addSubview:view]; + [view setFrame:[cocoa_view_.get() bounds]]; + [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + } } void TabContentsViewMac::SizeContents(const gfx::Size& size) { @@ -217,16 +223,6 @@ void TabContentsViewMac::Observe(NotificationType type, } break; } - case NotificationType::TAB_CONTENTS_DISCONNECTED: { - SadTabView* view = [[SadTabView alloc] initWithFrame:NSZeroRect]; - sad_tab_.reset(view); - - // Set as the dominant child. - [cocoa_view_.get() addSubview:view]; - [view setFrame:[cocoa_view_.get() bounds]]; - [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - break; - } default: NOTREACHED() << "Got a notification we didn't register for."; } diff --git a/chrome/browser/tab_contents/tab_contents_view_win.cc b/chrome/browser/tab_contents/tab_contents_view_win.cc index a5ec7f4..ed72402 100644 --- a/chrome/browser/tab_contents/tab_contents_view_win.cc +++ b/chrome/browser/tab_contents/tab_contents_view_win.cc @@ -218,7 +218,9 @@ void TabContentsViewWin::SetPageTitle(const std::wstring& title) { } } -void TabContentsViewWin::Invalidate() { +void TabContentsViewWin::OnTabCrashed() { + // Force an invalidation to render sad tab. We will notice we crashed when we + // paint. // Note that it's possible to get this message after the window was destroyed. if (::IsWindow(GetNativeView())) InvalidateRect(GetNativeView(), NULL, FALSE); diff --git a/chrome/browser/tab_contents/tab_contents_view_win.h b/chrome/browser/tab_contents/tab_contents_view_win.h index 4166891..b4d360b 100644 --- a/chrome/browser/tab_contents/tab_contents_view_win.h +++ b/chrome/browser/tab_contents/tab_contents_view_win.h @@ -37,7 +37,7 @@ class TabContentsViewWin : public TabContentsView, virtual void GetContainerBounds(gfx::Rect* out) const; virtual void OnContentsDestroy(); virtual void SetPageTitle(const std::wstring& title); - virtual void Invalidate(); + virtual void OnTabCrashed(); virtual void SizeContents(const gfx::Size& size); virtual void Focus(); virtual void SetInitialFocus(); |