diff options
author | gspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-19 17:50:36 +0000 |
---|---|---|
committer | gspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-19 17:50:36 +0000 |
commit | b121b1261952cf3490c3c79dad6a8d2262765101 (patch) | |
tree | 14d3644169c8533c283def215580fd0adf1c9130 /chrome | |
parent | 613c37ff0448b7767006137f3ea396c94b895fdc (diff) | |
download | chromium_src-b121b1261952cf3490c3c79dad6a8d2262765101.zip chromium_src-b121b1261952cf3490c3c79dad6a8d2262765101.tar.gz chromium_src-b121b1261952cf3490c3c79dad6a8d2262765101.tar.bz2 |
This adds some plumbing for propagating the status and error code of a
renderer process that went away so that we can tell at the UI level
what happened to the tab: did it crash, or was it killed by the OOM
killer (or some other reason). This is in preparation for implementing
a new UI for when a process is killed by the OOM on ChromeOS which
handles it differently from a crash.
Most of the changes are modifications of the argument list to include
a status and error code for the exited process, but in addition the
following was done:
- Changed the name of DidProcessCrash to GetTerminationStatus.
- Added some new enum values to TerminationStatus enum (and named it)
in process_util.h, so it can be used as the status returned by
WhatHappenedToProcess.
- Improved process_util_unittest to actually test for crashing and
terminated processes on all platforms.
- Added a new notification for renderers that were killed.
- Added error code information to crash notification.
- Added status and error code information to renderer IPC message for
RenderViewGone.
- Added a UMA histogram count for number of renderer kills.
[This change was previously reviewed and LGTM'd:
http://codereview.chromium.org/3386014/show
but due to issues with "git cl push" was never committed to the tree.]
BUG=none
TEST=ran new unit test. Test passes on try servers.
Review URL: http://codereview.chromium.org/3869001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63067 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
49 files changed, 230 insertions, 131 deletions
diff --git a/chrome/browser/browser_child_process_host.cc b/chrome/browser/browser_child_process_host.cc index a317f26..35660ab 100644 --- a/chrome/browser/browser_child_process_host.cc +++ b/chrome/browser/browser_child_process_host.cc @@ -131,18 +131,34 @@ void BrowserChildProcessHost::Notify(NotificationType type) { BrowserThread::UI, FROM_HERE, new ChildNotificationTask(type, this)); } -bool BrowserChildProcessHost::DidChildCrash() { - return child_process_->DidProcessCrash(); +base::TerminationStatus BrowserChildProcessHost::GetChildTerminationStatus( + int* exit_code) { + return child_process_->GetChildTerminationStatus(exit_code); } void BrowserChildProcessHost::OnChildDied() { if (handle() != base::kNullProcessHandle) { - bool did_crash = DidChildCrash(); - if (did_crash) { - OnProcessCrashed(); - // Report that this child process crashed. - Notify(NotificationType::CHILD_PROCESS_CRASHED); - UMA_HISTOGRAM_COUNTS("ChildProcess.Crashes", this->type()); + int exit_code; + base::TerminationStatus status = GetChildTerminationStatus(&exit_code); + switch (status) { + case base::TERMINATION_STATUS_PROCESS_CRASHED: { + OnProcessCrashed(exit_code); + + // Report that this child process crashed. + Notify(NotificationType::CHILD_PROCESS_CRASHED); + UMA_HISTOGRAM_COUNTS("ChildProcess.Crashes", this->type()); + break; + } + case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: { + OnProcessWasKilled(exit_code); + + // Report that this child process was killed. + Notify(NotificationType::CHILD_PROCESS_WAS_KILLED); + UMA_HISTOGRAM_COUNTS("ChildProcess.Kills", this->type()); + break; + } + default: + break; } // Notify in the main loop of the disconnection. Notify(NotificationType::CHILD_PROCESS_HOST_DISCONNECTED); diff --git a/chrome/browser/browser_child_process_host.h b/chrome/browser/browser_child_process_host.h index cf30973..9d343d09 100644 --- a/chrome/browser/browser_child_process_host.h +++ b/chrome/browser/browser_child_process_host.h @@ -74,12 +74,25 @@ class BrowserChildProcessHost : public ResourceDispatcherHost::Receiver, CommandLine* cmd_line); // ChildProcessLauncher::Client implementation. - virtual void OnProcessLaunched() { } + virtual void OnProcessLaunched() {} // Derived classes can override this to know if the process crashed. - virtual void OnProcessCrashed() {} - - virtual bool DidChildCrash(); + // |exit_code| is the status returned when the process crashed (for + // posix, as returned from waitpid(), for Windows, as returned from + // GetExitCodeProcess()). + virtual void OnProcessCrashed(int exit_code) {} + + // Derived classes can override this to know if the process was + // killed. |exit_code| is the status returned when the process + // was killed (for posix, as returned from waitpid(), for Windows, + // as returned from GetExitCodeProcess()). + virtual void OnProcessWasKilled(int exit_code) {} + + // Returns the termination status of a child. |exit_code| is the + // status returned when the process exited (for posix, as returned + // from waitpid(), for Windows, as returned from + // GetExitCodeProcess()). |exit_code| may be NULL. + virtual base::TerminationStatus GetChildTerminationStatus(int* exit_code); // Overrides from ChildProcessHost virtual void OnChildDied(); @@ -107,4 +120,3 @@ class BrowserChildProcessHost : public ResourceDispatcherHost::Receiver, }; #endif // CHROME_BROWSER_BROWSER_CHILD_PROCESS_HOST_H_ - diff --git a/chrome/browser/child_process_launcher.cc b/chrome/browser/child_process_launcher.cc index f215084..426fc4c 100644 --- a/chrome/browser/child_process_launcher.cc +++ b/chrome/browser/child_process_launcher.cc @@ -310,27 +310,30 @@ base::ProcessHandle ChildProcessLauncher::GetHandle() { return context_->process_.handle(); } -bool ChildProcessLauncher::DidProcessCrash() { - bool did_crash, child_exited; +base::TerminationStatus ChildProcessLauncher::GetChildTerminationStatus( + int* exit_code) { + base::TerminationStatus status; base::ProcessHandle handle = context_->process_.handle(); #if defined(OS_LINUX) if (context_->zygote_) { - did_crash = Singleton<ZygoteHost>()->DidProcessCrash(handle, &child_exited); + status = Singleton<ZygoteHost>()->GetTerminationStatus(handle, + exit_code); } else #endif { - did_crash = base::DidProcessCrash(&child_exited, handle); + status = base::GetTerminationStatus(handle, exit_code); } - // POSIX: If the process crashed, then the kernel closed the socket for it - // and so the child has already died by the time we get here. Since - // DidProcessCrash called waitpid with WNOHANG, it'll reap the process. - // However, if DidProcessCrash didn't reap the child, we'll need to in + // POSIX: If the process crashed, then the kernel closed the socket + // for it and so the child has already died by the time we get + // here. Since GetTerminationStatus called waitpid with WNOHANG, + // it'll reap the process. However, if GetTerminationStatus didn't + // reap the child (because it was still running), we'll need to // Terminate via ProcessWatcher. So we can't close the handle here. - if (child_exited) + if (status != base::TERMINATION_STATUS_STILL_RUNNING) context_->process_.Close(); - return did_crash; + return status; } void ChildProcessLauncher::SetProcessBackgrounded(bool background) { diff --git a/chrome/browser/child_process_launcher.h b/chrome/browser/child_process_launcher.h index 95fb6ea..a3add53 100644 --- a/chrome/browser/child_process_launcher.h +++ b/chrome/browser/child_process_launcher.h @@ -50,8 +50,11 @@ class ChildProcessLauncher { // Getter for the process handle. Only call after the process has started. base::ProcessHandle GetHandle(); - // Call this when the process exits to know if a process crashed or not. - bool DidProcessCrash(); + // Call this when the child process exits to know what happened to + // it. |exit_code| is the exit code of the process if it exited + // (e.g. status from waitpid if on posix, from GetExitCodeProcess on + // Windows). |exit_code| may be NULL. + base::TerminationStatus GetChildTerminationStatus(int* exit_code); // Changes whether the process runs in the background or not. Only call // this after the process has started. diff --git a/chrome/browser/child_process_security_policy_browsertest.cc b/chrome/browser/child_process_security_policy_browsertest.cc index 336ba24..5c51b75 100644 --- a/chrome/browser/child_process_security_policy_browsertest.cc +++ b/chrome/browser/child_process_security_policy_browsertest.cc @@ -43,7 +43,7 @@ IN_PROC_BROWSER_TEST_F(ChildProcessSecurityPolicyInProcessBrowserTest, NoLeak) { TabContents* tab = browser()->GetTabContentsAt(0); ASSERT_TRUE(tab != NULL); base::KillProcess(tab->GetRenderProcessHost()->GetHandle(), - base::PROCESS_END_KILLED_BY_USER, true); + base::TERMINATION_STATUS_PROCESS_WAS_KILLED, true); tab->controller().Reload(true); EXPECT_EQ( diff --git a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc index 32b67af..4518569 100644 --- a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc +++ b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc @@ -61,7 +61,7 @@ class ExtensionCrashRecoveryTest : public ExtensionBrowserTest { RenderProcessHost* extension_rph = extension_host->render_view_host()->process(); base::KillProcess(extension_rph->GetHandle(), - base::PROCESS_END_KILLED_BY_USER, false); + base::TERMINATION_STATUS_PROCESS_WAS_KILLED, false); ASSERT_TRUE(WaitForExtensionCrash(extension_id)); ASSERT_FALSE( GetExtensionProcessManager()->GetBackgroundHostForExtension(extension)); diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.cc b/chrome/browser/extensions/sandboxed_extension_unpacker.cc index fc8aea8..300582d 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker.cc +++ b/chrome/browser/extensions/sandboxed_extension_unpacker.cc @@ -172,7 +172,7 @@ void SandboxedExtensionUnpacker::OnUnpackExtensionFailed( ReportFailure(error); } -void SandboxedExtensionUnpacker::OnProcessCrashed() { +void SandboxedExtensionUnpacker::OnProcessCrashed(int exit_code) { // Don't report crashes if they happen after we got a response. if (got_response_) return; diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.h b/chrome/browser/extensions/sandboxed_extension_unpacker.h index 8df1414..794f2e1 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker.h +++ b/chrome/browser/extensions/sandboxed_extension_unpacker.h @@ -124,7 +124,7 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client { // SandboxedExtensionUnpacker void OnUnpackExtensionSucceeded(const DictionaryValue& manifest); void OnUnpackExtensionFailed(const std::string& error_message); - void OnProcessCrashed(); + void OnProcessCrashed(int exit_code); void ReportFailure(const std::string& message); void ReportSuccess(); diff --git a/chrome/browser/importer/importer.cc b/chrome/browser/importer/importer.cc index 9a40471..766e59e 100644 --- a/chrome/browser/importer/importer.cc +++ b/chrome/browser/importer/importer.cc @@ -437,7 +437,7 @@ void ExternalProcessImporterClient::NotifyItemFinishedOnIOThread( profile_import_process_host_->ReportImportItemFinished(import_item); } -void ExternalProcessImporterClient::OnProcessCrashed() { +void ExternalProcessImporterClient::OnProcessCrashed(int exit_code) { if (cancelled_) return; diff --git a/chrome/browser/importer/importer.h b/chrome/browser/importer/importer.h index 4887138..d1668d3 100644 --- a/chrome/browser/importer/importer.h +++ b/chrome/browser/importer/importer.h @@ -327,7 +327,7 @@ class ExternalProcessImporterClient void NotifyItemFinishedOnIOThread(importer::ImportItem import_item); // Cancel import on process crash. - virtual void OnProcessCrashed(); + virtual void OnProcessCrashed(int exit_code); // Notifies the importerhost that import has finished, and calls Release(). void Cleanup(); diff --git a/chrome/browser/in_process_webkit/indexed_db_key_utility_client.cc b/chrome/browser/in_process_webkit/indexed_db_key_utility_client.cc index 6667d50..e287c2c 100644 --- a/chrome/browser/in_process_webkit/indexed_db_key_utility_client.cc +++ b/chrome/browser/in_process_webkit/indexed_db_key_utility_client.cc @@ -1,6 +1,6 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this -// source code is governed by a BSD-style license that can be found in the -// LICENSE file. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. #include "chrome/browser/in_process_webkit/indexed_db_key_utility_client.h" @@ -148,7 +148,7 @@ IndexedDBKeyUtilityClient::Client::Client(IndexedDBKeyUtilityClient* parent) : parent_(parent) { } -void IndexedDBKeyUtilityClient::Client::OnProcessCrashed() { +void IndexedDBKeyUtilityClient::Client::OnProcessCrashed(int exit_code) { if (parent_->state_ == STATE_CREATING_KEYS) parent_->FinishCreatingKeys(); } diff --git a/chrome/browser/in_process_webkit/indexed_db_key_utility_client.h b/chrome/browser/in_process_webkit/indexed_db_key_utility_client.h index ee03ed9..6b8aec1 100644 --- a/chrome/browser/in_process_webkit/indexed_db_key_utility_client.h +++ b/chrome/browser/in_process_webkit/indexed_db_key_utility_client.h @@ -45,7 +45,7 @@ class IndexedDBKeyUtilityClient explicit Client(IndexedDBKeyUtilityClient* parent); // UtilityProcessHost::Client - virtual void OnProcessCrashed(); + virtual void OnProcessCrashed(int exit_code); virtual void OnIDBKeysFromValuesAndKeyPathSucceeded( int id, const std::vector<IndexedDBKey>& keys); virtual void OnIDBKeysFromValuesAndKeyPathFailed(int id); diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc index 37b79b7..49f3fdb 100644 --- a/chrome/browser/metrics/metrics_service.cc +++ b/chrome/browser/metrics/metrics_service.cc @@ -610,7 +610,8 @@ void MetricsService::Observe(NotificationType type, { RenderProcessHost::RendererClosedDetails* process_details = Details<RenderProcessHost::RendererClosedDetails>(details).ptr(); - if (process_details->did_crash) { + if (process_details->status == + base::TERMINATION_STATUS_PROCESS_CRASHED) { if (process_details->was_extension_renderer) { LogExtensionRendererCrash(); } else { diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc index 1ee53b9..2540d8c 100644 --- a/chrome/browser/nacl_host/nacl_process_host.cc +++ b/chrome/browser/nacl_host/nacl_process_host.cc @@ -162,10 +162,11 @@ void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { OnProcessLaunched(); } -bool NaClProcessHost::DidChildCrash() { +base::TerminationStatus NaClProcessHost::GetChildTerminationStatus( + int* exit_code) { if (running_on_wow64_) - return base::DidProcessCrash(NULL, handle()); - return BrowserChildProcessHost::DidChildCrash(); + return base::GetTerminationStatus(handle(), exit_code); + return BrowserChildProcessHost::GetChildTerminationStatus(exit_code); } void NaClProcessHost::OnChildDied() { diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h index 618492a..afd3e2d 100644 --- a/chrome/browser/nacl_host/nacl_process_host.h +++ b/chrome/browser/nacl_host/nacl_process_host.h @@ -37,7 +37,7 @@ class NaClProcessHost : public BrowserChildProcessHost { void OnProcessLaunchedByBroker(base::ProcessHandle handle); protected: - virtual bool DidChildCrash(); + virtual base::TerminationStatus GetChildTerminationStatus(int* exit_code); virtual void OnChildDied(); private: diff --git a/chrome/browser/profile_import_process_host.cc b/chrome/browser/profile_import_process_host.cc index 26e4ec1..45ec4f6 100644 --- a/chrome/browser/profile_import_process_host.cc +++ b/chrome/browser/profile_import_process_host.cc @@ -127,12 +127,13 @@ void ProfileImportProcessHost::OnMessageReceived(const IPC::Message& message) { message)); } -void ProfileImportProcessHost::OnProcessCrashed() { +void ProfileImportProcessHost::OnProcessCrashed(int exit_code) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); BrowserThread::PostTask( thread_id_, FROM_HERE, NewRunnableMethod(import_process_client_.get(), - &ImportProcessClient::OnProcessCrashed)); + &ImportProcessClient::OnProcessCrashed, + exit_code)); } bool ProfileImportProcessHost::CanShutdown() { diff --git a/chrome/browser/profile_import_process_host.h b/chrome/browser/profile_import_process_host.h index a9d5805..2e77573d 100644 --- a/chrome/browser/profile_import_process_host.h +++ b/chrome/browser/profile_import_process_host.h @@ -40,7 +40,7 @@ class ProfileImportProcessHost : public BrowserChildProcessHost { // These methods are used by the ProfileImportProcessHost to pass messages // received from the external process back to the ImportProcessClient in // ImporterHost. - virtual void OnProcessCrashed() {} + virtual void OnProcessCrashed(int exit_status) {} virtual void OnImportStart() {} virtual void OnImportFinished(bool succeeded, std::string error_msg) {} virtual void OnImportItemStart(int item) {} @@ -126,7 +126,7 @@ class ProfileImportProcessHost : public BrowserChildProcessHost { void OnMessageReceived(const IPC::Message& message); // Overridden from BrowserChildProcessHost: - virtual void OnProcessCrashed(); + virtual void OnProcessCrashed(int exit_code); virtual bool CanShutdown(); virtual URLRequestContext* GetRequestContext( uint32 request_id, diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 5e254e5..1832464 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -924,16 +924,20 @@ void BrowserRenderProcessHost::OnChannelError() { if (!channel_.get()) return; - // NULL in single process mode or if fast termination happened. - bool did_crash = - child_process_.get() ? child_process_->DidProcessCrash() : false; - - if (did_crash) { + // child_process_ can be NULL in single process mode or if fast + // termination happened. + int exit_code = 0; + base::TerminationStatus status = + child_process_.get() ? + child_process_->GetChildTerminationStatus(&exit_code) : + base::TERMINATION_STATUS_NORMAL_TERMINATION; + + if (status == base::TERMINATION_STATUS_PROCESS_CRASHED) { UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes", extension_process_ ? 2 : 1); } - RendererClosedDetails details(did_crash, extension_process_); + RendererClosedDetails details(status, exit_code, extension_process_); NotificationService::current()->Notify( NotificationType::RENDERER_PROCESS_CLOSED, Source<RenderProcessHost>(this), @@ -946,7 +950,9 @@ void BrowserRenderProcessHost::OnChannelError() { IDMap<IPC::Channel::Listener>::iterator iter(&listeners_); while (!iter.IsAtEnd()) { iter.GetCurrentValue()->OnMessageReceived( - ViewHostMsg_RenderViewGone(iter.GetCurrentKey())); + ViewHostMsg_RenderViewGone(iter.GetCurrentKey(), + static_cast<int>(status), + exit_code)); iter.Advance(); } diff --git a/chrome/browser/renderer_host/render_process_host.h b/chrome/browser/renderer_host/render_process_host.h index a5fd378..c9a8abc 100644 --- a/chrome/browser/renderer_host/render_process_host.h +++ b/chrome/browser/renderer_host/render_process_host.h @@ -11,6 +11,7 @@ #include "app/surface/transport_dib.h" #include "base/id_map.h" #include "base/process.h" +#include "base/process_util.h" #include "base/scoped_ptr.h" #include "base/time.h" #include "chrome/common/visitedlink_common.h" @@ -48,11 +49,15 @@ class RenderProcessHost : public IPC::Channel::Sender, // Details for RENDERER_PROCESS_CLOSED notifications. struct RendererClosedDetails { - RendererClosedDetails(bool did_crash, bool was_extension_renderer) { - this->did_crash = did_crash; + RendererClosedDetails(base::TerminationStatus status, + int exit_code, + bool was_extension_renderer) { + this->status = status; + this->exit_code = exit_code; this->was_extension_renderer = was_extension_renderer; } - bool did_crash; + base::TerminationStatus status; + int exit_code; bool was_extension_renderer; }; diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 3781bed..21c3675 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -981,11 +981,13 @@ void RenderViewHost::OnMsgRenderViewReady() { delegate_->RenderViewReady(this); } -void RenderViewHost::OnMsgRenderViewGone() { +void RenderViewHost::OnMsgRenderViewGone(int status, int exit_code) { // Our base class RenderWidgetHost needs to reset some stuff. - RendererExited(); + RendererExited(static_cast<base::TerminationStatus>(status), exit_code); - delegate_->RenderViewGone(this); + delegate_->RenderViewGone(this, + static_cast<base::TerminationStatus>(status), + exit_code); } // Called when the renderer navigates. For every frame loaded, we'll get this diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 76f1f01..1636d4e 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -525,7 +525,7 @@ class RenderViewHost : public RenderWidgetHost { void OnMsgShowFullscreenWidget(int route_id); void OnMsgRunModal(IPC::Message* reply_msg); void OnMsgRenderViewReady(); - void OnMsgRenderViewGone(); + void OnMsgRenderViewGone(int status, int error_code); void OnMsgNavigate(const IPC::Message& msg); void OnMsgUpdateState(int32 page_id, const std::string& state); diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index d0c88d6..a75cb1d 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -10,6 +10,7 @@ #include <vector> #include "base/basictypes.h" +#include "base/process_util.h" #include "base/ref_counted.h" #include "base/string16.h" #include "chrome/common/content_settings_types.h" @@ -682,7 +683,9 @@ class RenderViewHostDelegate { virtual void RenderViewReady(RenderViewHost* render_view_host) {} // The RenderView died somehow (crashed or was killed by the user). - virtual void RenderViewGone(RenderViewHost* render_view_host) {} + virtual void RenderViewGone(RenderViewHost* render_view_host, + base::TerminationStatus status, + int error_code) {} // The RenderView is going to be deleted. This is called when each // RenderView is going to be destroyed diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index a6efd58..1487899 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -601,7 +601,8 @@ void RenderWidgetHost::ForwardEditCommandsForNextKeyEvent( // only handled by RenderView. } -void RenderWidgetHost::RendererExited() { +void RenderWidgetHost::RendererExited(base::TerminationStatus status, + int exit_code) { // Clearing this flag causes us to re-create the renderer when recovering // from a crashed renderer. renderer_initialized_ = false; @@ -626,7 +627,7 @@ void RenderWidgetHost::RendererExited() { is_hidden_ = false; if (view_) { - view_->RenderViewGone(); + view_->RenderViewGone(status, exit_code); view_ = NULL; // The View should be deleted by RenderViewGone. } @@ -736,7 +737,7 @@ void RenderWidgetHost::OnMsgRenderViewReady() { WasResized(); } -void RenderWidgetHost::OnMsgRenderViewGone() { +void RenderWidgetHost::OnMsgRenderViewGone(int status, int exit_code) { // TODO(evanm): This synchronously ends up calling "delete this". // Is that really what we want in response to this message? I'm matching // previous behavior of the code here. diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h index 6c3fed7..297d74a 100644 --- a/chrome/browser/renderer_host/render_widget_host.h +++ b/chrome/browser/renderer_host/render_widget_host.h @@ -12,6 +12,7 @@ #include "app/surface/transport_dib.h" #include "base/gtest_prod_util.h" +#include "base/process_util.h" #include "base/scoped_ptr.h" #include "base/string16.h" #include "base/timer.h" @@ -414,7 +415,7 @@ class RenderWidgetHost : public IPC::Channel::Listener, // Called when we receive a notification indicating that the renderer // process has gone. This will reset our state so that our state will be // consistent if a new renderer is created. - void RendererExited(); + void RendererExited(base::TerminationStatus status, int exit_code); // Retrieves an id the renderer can use to refer to its view. // This is used for various IPC messages, including plugins. @@ -474,7 +475,7 @@ class RenderWidgetHost : public IPC::Channel::Listener, // IPC message handlers void OnMsgRenderViewReady(); - void OnMsgRenderViewGone(); + void OnMsgRenderViewGone(int status, int error_code); void OnMsgClose(); void OnMsgRequestMove(const gfx::Rect& pos); void OnMsgPaintAtSizeAck(int tag, const gfx::Size& size); diff --git a/chrome/browser/renderer_host/render_widget_host_unittest.cc b/chrome/browser/renderer_host/render_widget_host_unittest.cc index 1c5bb17..9bd4fa3 100644 --- a/chrome/browser/renderer_host/render_widget_host_unittest.cc +++ b/chrome/browser/renderer_host/render_widget_host_unittest.cc @@ -392,7 +392,7 @@ TEST_F(RenderWidgetHostTest, ResizeThenCrash) { // resize ack logic is cleared. Must clear the view first so it doesn't get // deleted. host_->set_view(NULL); - host_->RendererExited(); + host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1); EXPECT_FALSE(host_->resize_ack_pending_); EXPECT_EQ(gfx::Size(), host_->in_flight_size_); diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h index 46d6bda..074fc88 100644 --- a/chrome/browser/renderer_host/render_widget_host_view.h +++ b/chrome/browser/renderer_host/render_widget_host_view.h @@ -14,10 +14,11 @@ #include <vector> #include "app/surface/transport_dib.h" +#include "base/process_util.h" #include "gfx/native_widget_types.h" -#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/WebKit/WebKit/chromium/public/WebPopupType.h" #include "third_party/WebKit/WebKit/chromium/public/WebTextInputType.h" +#include "third_party/skia/include/core/SkBitmap.h" namespace gfx { class Rect; @@ -152,7 +153,8 @@ class RenderWidgetHostView { const std::vector<gfx::Rect>& copy_rects) = 0; // Notifies the View that the renderer has ceased to exist. - virtual void RenderViewGone() = 0; + virtual void RenderViewGone(base::TerminationStatus status, + int error_code) = 0; // Notifies the View that the renderer will be delete soon. virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) = 0; diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc index 5f4a843..77802a6 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -671,7 +671,8 @@ void RenderWidgetHostViewGtk::DidUpdateBackingStore( } } -void RenderWidgetHostViewGtk::RenderViewGone() { +void RenderWidgetHostViewGtk::RenderViewGone(base::TerminationStatus status, + int error_code) { Destroy(); plugin_container_manager_.set_host_widget(NULL); } diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.h b/chrome/browser/renderer_host/render_widget_host_view_gtk.h index 099da46..10a7626 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.h +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.h @@ -75,7 +75,8 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView { virtual void DidUpdateBackingStore( const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, const std::vector<gfx::Rect>& copy_rects); - virtual void RenderViewGone(); + virtual void RenderViewGone(base::TerminationStatus status, + int error_code); virtual void Destroy(); virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {} virtual void SetTooltipText(const std::wstring& tooltip_text); diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h index b9e41f9..909626e 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.h +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h @@ -207,7 +207,8 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView { virtual void DidUpdateBackingStore( const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, const std::vector<gfx::Rect>& copy_rects); - virtual void RenderViewGone(); + virtual void RenderViewGone(base::TerminationStatus status, + int error_code); virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {}; virtual void Destroy(); virtual void SetTooltipText(const std::wstring& tooltip_text); diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm index 3281a0e..65473ed 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm @@ -713,7 +713,8 @@ void RenderWidgetHostViewMac::DidUpdateBackingStore( [cocoa_view_ displayIfNeeded]; } -void RenderWidgetHostViewMac::RenderViewGone() { +void RenderWidgetHostViewMac::RenderViewGone(base::TerminationStatus status, + int error_code) { // TODO(darin): keep this around, and draw sad-tab into it. UpdateCursorIfOverSelf(); Destroy(); diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.cc b/chrome/browser/renderer_host/render_widget_host_view_views.cc index 25e8a88..f0a044f 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_views.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_views.cc @@ -215,7 +215,8 @@ void RenderWidgetHostViewViews::DidUpdateBackingStore( } } -void RenderWidgetHostViewViews::RenderViewGone() { +void RenderWidgetHostViewViews::RenderViewGone(base::TerminationStatus status, + int error_code) { Destroy(); } @@ -313,7 +314,7 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) { DCHECK(!about_to_validate_and_paint_); // TODO(anicolao): get the damage somehow - //invalid_rect_ = damage_rect; + // invalid_rect_ = damage_rect; invalid_rect_ = bounds(); about_to_validate_and_paint_ = true; BackingStoreX* backing_store = static_cast<BackingStoreX*>( diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.h b/chrome/browser/renderer_host/render_widget_host_view_views.h index 331c1cd..3771393 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_views.h +++ b/chrome/browser/renderer_host/render_widget_host_view_views.h @@ -60,7 +60,8 @@ class RenderWidgetHostViewViews : public RenderWidgetHostView, virtual void DidUpdateBackingStore( const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, const std::vector<gfx::Rect>& copy_rects); - virtual void RenderViewGone(); + virtual void RenderViewGone(base::TerminationStatus status, + int error_code); virtual void Destroy(); virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {} virtual void SetTooltipText(const std::wstring& tooltip_text); diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc index 0b66f0c..ff90c06 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc @@ -736,7 +736,8 @@ void RenderWidgetHostViewWin::DidUpdateBackingStore( Redraw(); } -void RenderWidgetHostViewWin::RenderViewGone() { +void RenderWidgetHostViewWin::RenderViewGone(base::TerminationStatus status, + int error_code) { // TODO(darin): keep this around, and draw sad-tab into it. UpdateCursorIfOverSelf(); being_destroyed_ = true; diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.h b/chrome/browser/renderer_host/render_widget_host_view_win.h index 9fbaf11..c401005 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.h +++ b/chrome/browser/renderer_host/render_widget_host_view_win.h @@ -144,7 +144,8 @@ class RenderWidgetHostViewWin virtual void DidUpdateBackingStore( const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, const std::vector<gfx::Rect>& copy_rects); - virtual void RenderViewGone(); + virtual void RenderViewGone(base::TerminationStatus status, + int error_code); virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh); virtual void Destroy(); virtual void SetTooltipText(const std::wstring& tooltip_text); diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h index e3c9f39..e3c22c14 100644 --- a/chrome/browser/renderer_host/test/test_render_view_host.h +++ b/chrome/browser/renderer_host/test/test_render_view_host.h @@ -81,7 +81,8 @@ class TestRenderWidgetHostView : public RenderWidgetHostView { virtual void DidUpdateBackingStore( const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, const std::vector<gfx::Rect>& rects) {} - virtual void RenderViewGone() { delete this; } + virtual void RenderViewGone(base::TerminationStatus status, + int error_code) { delete this; } virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) { } virtual void Destroy() {} virtual void PrepareToDestroy() {} diff --git a/chrome/browser/renderer_host/test/web_cache_manager_browsertest.cc b/chrome/browser/renderer_host/test/web_cache_manager_browsertest.cc index 0779b00..84dbde0 100644 --- a/chrome/browser/renderer_host/test/web_cache_manager_browsertest.cc +++ b/chrome/browser/renderer_host/test/web_cache_manager_browsertest.cc @@ -33,7 +33,7 @@ IN_PROC_BROWSER_TEST_F(WebCacheManagerBrowserTest, FLAKY_CrashOnceOnly) { TabContents* tab = browser()->GetTabContentsAt(0); ASSERT_TRUE(tab != NULL); base::KillProcess(tab->GetRenderProcessHost()->GetHandle(), - base::PROCESS_END_KILLED_BY_USER, true); + base::TERMINATION_STATUS_PROCESS_WAS_KILLED, true); browser()->SelectTabContentsAt(0, true); browser()->NewTab(); diff --git a/chrome/browser/tab_contents/interstitial_page.cc b/chrome/browser/tab_contents/interstitial_page.cc index 8663eef..8fd9f7f 100644 --- a/chrome/browser/tab_contents/interstitial_page.cc +++ b/chrome/browser/tab_contents/interstitial_page.cc @@ -327,7 +327,9 @@ const GURL& InterstitialPage::GetURL() const { return url_; } -void InterstitialPage::RenderViewGone(RenderViewHost* render_view_host) { +void InterstitialPage::RenderViewGone(RenderViewHost* render_view_host, + base::TerminationStatus status, + int error_code) { // Our renderer died. This should not happen in normal cases. // Just dismiss the interstitial. DontProceed(); diff --git a/chrome/browser/tab_contents/interstitial_page.h b/chrome/browser/tab_contents/interstitial_page.h index 50ede04..2faad77 100644 --- a/chrome/browser/tab_contents/interstitial_page.h +++ b/chrome/browser/tab_contents/interstitial_page.h @@ -9,6 +9,7 @@ #include <map> #include <string> +#include "base/process_util.h" #include "base/scoped_ptr.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/common/notification_observer.h" @@ -124,7 +125,9 @@ class InterstitialPage : public NotificationObserver, // RenderViewHostDelegate implementation: virtual View* GetViewDelegate(); virtual const GURL& GetURL() const; - virtual void RenderViewGone(RenderViewHost* render_view_host); + virtual void RenderViewGone(RenderViewHost* render_view_host, + base::TerminationStatus status, + int error_code); virtual void DidNavigate(RenderViewHost* render_view_host, const ViewHostMsg_FrameNavigate_Params& params); virtual void UpdateTitle(RenderViewHost* render_view_host, diff --git a/chrome/browser/tab_contents/web_contents_unittest.cc b/chrome/browser/tab_contents/web_contents_unittest.cc index abb1578..67d93a3 100644 --- a/chrome/browser/tab_contents/web_contents_unittest.cc +++ b/chrome/browser/tab_contents/web_contents_unittest.cc @@ -120,8 +120,8 @@ class TestInterstitialPage : public InterstitialPage { DidNavigate(render_view_host(), params); } - void TestRenderViewGone() { - RenderViewGone(render_view_host()); + void TestRenderViewGone(base::TerminationStatus status, int error_code) { + RenderViewGone(render_view_host(), status, error_code); } bool is_showing() const { @@ -1151,7 +1151,9 @@ TEST_F(TabContentsTest, ShowInterstitialCrashRendererThenGoBack) { interstitial->TestDidNavigate(2, interstitial_url); // Crash the renderer - rvh()->TestOnMessageReceived(ViewHostMsg_RenderViewGone(0)); + rvh()->TestOnMessageReceived( + ViewHostMsg_RenderViewGone( + 0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1)); // While the interstitial is showing, go back. controller().GoBack(); @@ -1186,7 +1188,9 @@ TEST_F(TabContentsTest, ShowInterstitialCrashRendererThenNavigate) { interstitial->Show(); // Crash the renderer - rvh()->TestOnMessageReceived(ViewHostMsg_RenderViewGone(0)); + rvh()->TestOnMessageReceived( + ViewHostMsg_RenderViewGone( + 0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1)); interstitial->TestDidNavigate(2, interstitial_url); } @@ -1429,7 +1433,8 @@ TEST_F(TabContentsTest, InterstitialCrasher) { TestInterstitialPageStateGuard state_guard(interstitial); interstitial->Show(); // Simulate a renderer crash before the interstitial is shown. - interstitial->TestRenderViewGone(); + interstitial->TestRenderViewGone( + base::TERMINATION_STATUS_PROCESS_CRASHED, -1); // The interstitial should have been dismissed. EXPECT_TRUE(deleted); EXPECT_EQ(TestInterstitialPage::CANCELED, state); @@ -1440,7 +1445,8 @@ TEST_F(TabContentsTest, InterstitialCrasher) { interstitial->Show(); interstitial->TestDidNavigate(1, url); // Simulate a renderer crash. - interstitial->TestRenderViewGone(); + interstitial->TestRenderViewGone( + base::TERMINATION_STATUS_PROCESS_CRASHED, -1); // The interstitial should have been dismissed. EXPECT_TRUE(deleted); EXPECT_EQ(TestInterstitialPage::CANCELED, state); diff --git a/chrome/browser/task_manager/task_manager.cc b/chrome/browser/task_manager/task_manager.cc index 0793a4d..df102e1 100644 --- a/chrome/browser/task_manager/task_manager.cc +++ b/chrome/browser/task_manager/task_manager.cc @@ -895,7 +895,7 @@ void TaskManager::KillProcess(int index) { base::ProcessHandle process = model_->GetResourceProcessHandle(index); DCHECK(process); if (process != base::GetCurrentProcessHandle()) - base::KillProcess(process, base::PROCESS_END_KILLED_BY_USER, false); + base::KillProcess(process, base::PROCESS_END_PROCESS_WAS_KILLED, false); } void TaskManager::ActivateProcess(int index) { diff --git a/chrome/browser/utility_process_host.cc b/chrome/browser/utility_process_host.cc index 22495f8..9805071 100644 --- a/chrome/browser/utility_process_host.cc +++ b/chrome/browser/utility_process_host.cc @@ -159,10 +159,10 @@ void UtilityProcessHost::OnMessageReceived(const IPC::Message& message) { NewRunnableMethod(client_.get(), &Client::OnMessageReceived, message)); } -void UtilityProcessHost::OnProcessCrashed() { +void UtilityProcessHost::OnProcessCrashed(int exit_code) { BrowserThread::PostTask( client_thread_id_, FROM_HERE, - NewRunnableMethod(client_.get(), &Client::OnProcessCrashed)); + NewRunnableMethod(client_.get(), &Client::OnProcessCrashed, exit_code)); } void UtilityProcessHost::Client::OnMessageReceived( diff --git a/chrome/browser/utility_process_host.h b/chrome/browser/utility_process_host.h index 48d5e38..da2a05a 100644 --- a/chrome/browser/utility_process_host.h +++ b/chrome/browser/utility_process_host.h @@ -39,7 +39,7 @@ class UtilityProcessHost : public BrowserChildProcessHost { Client() {} // Called when the process has crashed. - virtual void OnProcessCrashed() {} + virtual void OnProcessCrashed(int exit_code) {} // Called when the extension has unpacked successfully. |manifest| is the // parsed manifest.json file. |catalogs| contains list of all parsed @@ -153,7 +153,7 @@ class UtilityProcessHost : public BrowserChildProcessHost { void OnMessageReceived(const IPC::Message& message); // BrowserChildProcessHost: - virtual void OnProcessCrashed(); + virtual void OnProcessCrashed(int exit_code); virtual bool CanShutdown() { return true; } virtual URLRequestContext* GetRequestContext( uint32 request_id, diff --git a/chrome/browser/web_resource/web_resource_service.cc b/chrome/browser/web_resource/web_resource_service.cc index 7c8a1ba..dbc7fac 100644 --- a/chrome/browser/web_resource/web_resource_service.cc +++ b/chrome/browser/web_resource/web_resource_service.cc @@ -141,7 +141,7 @@ class WebResourceService::UnpackerClient ~UnpackerClient() {} // UtilityProcessHost::Client - virtual void OnProcessCrashed() { + virtual void OnProcessCrashed(int exit_code) { if (got_response_) return; diff --git a/chrome/browser/zygote_host_linux.cc b/chrome/browser/zygote_host_linux.cc index d88c9be..f88c597 100644 --- a/chrome/browser/zygote_host_linux.cc +++ b/chrome/browser/zygote_host_linux.cc @@ -306,13 +306,18 @@ void ZygoteHost::EnsureProcessTerminated(pid_t process) { PLOG(ERROR) << "write"; } -bool ZygoteHost::DidProcessCrash(base::ProcessHandle handle, - bool* child_exited) { +base::TerminationStatus ZygoteHost::GetTerminationStatus( + base::ProcessHandle handle, + int* exit_code) { DCHECK(init_); Pickle pickle; - pickle.WriteInt(kCmdDidProcessCrash); + pickle.WriteInt(kCmdGetTerminationStatus); pickle.WriteInt(handle); + // Set this now to handle the early termination cases. + if (exit_code) + *exit_code = 0; + static const unsigned kMaxMessageLength = 128; char buf[kMaxMessageLength]; ssize_t len; @@ -326,23 +331,23 @@ bool ZygoteHost::DidProcessCrash(base::ProcessHandle handle, if (len == -1) { LOG(WARNING) << "Error reading message from zygote: " << errno; - return false; + return base::TERMINATION_STATUS_NORMAL_TERMINATION; } else if (len == 0) { LOG(WARNING) << "Socket closed prematurely."; - return false; + return base::TERMINATION_STATUS_NORMAL_TERMINATION; } Pickle read_pickle(buf, len); - bool did_crash, tmp_child_exited; + int status, tmp_exit_code; void* iter = NULL; - if (!read_pickle.ReadBool(&iter, &did_crash) || - !read_pickle.ReadBool(&iter, &tmp_child_exited)) { - LOG(WARNING) << "Error parsing DidProcessCrash response from zygote."; - return false; + if (!read_pickle.ReadInt(&iter, &status) || + !read_pickle.ReadInt(&iter, &tmp_exit_code)) { + LOG(WARNING) << "Error parsing GetTerminationStatus response from zygote."; + return base::TERMINATION_STATUS_NORMAL_TERMINATION; } - if (child_exited) - *child_exited = tmp_child_exited; + if (exit_code) + *exit_code = tmp_exit_code; - return did_crash; + return static_cast<base::TerminationStatus>(status); } diff --git a/chrome/browser/zygote_host_linux.h b/chrome/browser/zygote_host_linux.h index dd00336..68a72ed 100644 --- a/chrome/browser/zygote_host_linux.h +++ b/chrome/browser/zygote_host_linux.h @@ -14,6 +14,7 @@ #include "base/global_descriptors_posix.h" #include "base/lock.h" #include "base/process.h" +#include "base/process_util.h" template<typename Type> struct DefaultSingletonTraits; @@ -34,17 +35,18 @@ class ZygoteHost { const base::GlobalDescriptors::Mapping& mapping); void EnsureProcessTerminated(pid_t process); - // Get the termination status (exit code) of the process and return true if - // the status indicates the process crashed. |child_exited| is set to true - // iff the child process has terminated. (|child_exited| may be NULL.) - bool DidProcessCrash(base::ProcessHandle handle, bool* child_exited); + // Get the termination status (and, optionally, the exit code) of + // the process. |exit_code| is set to the exit code of the child + // process. (|exit_code| may be NULL.) + base::TerminationStatus GetTerminationStatus(base::ProcessHandle handle, + int* exit_code); // These are the command codes used on the wire between the browser and the // zygote. enum { kCmdFork = 0, // Fork off a new renderer. kCmdReap = 1, // Reap a renderer child. - kCmdDidProcessCrash = 2, // Check if child process crashed. + kCmdGetTerminationStatus = 2, // Check what happend to a child process. kCmdGetSandboxStatus = 3, // Read a bitmask of kSandbox* }; diff --git a/chrome/browser/zygote_main_linux.cc b/chrome/browser/zygote_main_linux.cc index 65a44ae..2ab36e2 100644 --- a/chrome/browser/zygote_main_linux.cc +++ b/chrome/browser/zygote_main_linux.cc @@ -167,10 +167,10 @@ class Zygote { break; HandleReapRequest(fd, pickle, iter); return false; - case ZygoteHost::kCmdDidProcessCrash: + case ZygoteHost::kCmdGetTerminationStatus: if (!fds.empty()) break; - HandleDidProcessCrash(fd, pickle, iter); + HandleGetTerminationStatus(fd, pickle, iter); return false; case ZygoteHost::kCmdGetSandboxStatus: HandleGetSandboxStatus(fd, pickle, iter); @@ -209,26 +209,31 @@ class Zygote { ProcessWatcher::EnsureProcessTerminated(actual_child); } - void HandleDidProcessCrash(int fd, const Pickle& pickle, void* iter) { + void HandleGetTerminationStatus(int fd, const Pickle& pickle, void* iter) { base::ProcessHandle child; if (!pickle.ReadInt(&iter, &child)) { - LOG(WARNING) << "Error parsing DidProcessCrash request from browser"; + LOG(WARNING) << "Error parsing GetTerminationStatus request " + << "from browser"; return; } - bool child_exited; - bool did_crash; + base::TerminationStatus status; + int exit_code; if (g_suid_sandbox_active) child = real_pids_to_sandbox_pids[child]; - if (child) - did_crash = base::DidProcessCrash(&child_exited, child); - else - did_crash = child_exited = false; + if (child) { + status = base::GetTerminationStatus(child, &exit_code); + } else { + // Assume that if we can't find the child in the sandbox, then + // it terminated normally. + status = base::TERMINATION_STATUS_NORMAL_TERMINATION; + exit_code = 0; + } Pickle write_pickle; - write_pickle.WriteBool(did_crash); - write_pickle.WriteBool(child_exited); + write_pickle.WriteInt(static_cast<int>(status)); + write_pickle.WriteInt(exit_code); if (HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())) != write_pickle.size()) { PLOG(ERROR) << "write"; diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index 1ba2c39..5de67e7 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -537,12 +537,20 @@ class NotificationType { // The details are in a Details<ChildProcessInfo>. CHILD_PROCESS_HOST_DISCONNECTED, - // This message is sent when a child process disappears unexpectedly. - // There is no usable source, since it is sent from an ephemeral task; - // register for AllSources() to receive this notification. The details are - // in a Details<ChildProcessInfo>. + // This message is sent when a child process disappears + // unexpectedly as a result of a crash. There is no usable + // source, since it is sent from an ephemeral task; register for + // AllSources() to receive this notification. The details are in + // a Details<ChildProcessInfo>. CHILD_PROCESS_CRASHED, + // This message is sent when a child process disappears + // unexpectedly as a result of a termination signal. There is no + // usable source, since it is sent from an ephemeral task; + // register for AllSources() to receive this notification. The + // details are in a Details<ChildProcessInfo>. + CHILD_PROCESS_WAS_KILLED, + // This message indicates that an instance of a particular child was // created in a page. (If one page contains several regions rendered by // the same child, this notification will occur once for each region diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 75eacdf..40c1886 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -1163,7 +1163,9 @@ IPC_BEGIN_MESSAGES(ViewHost) // Indicates the renderer process is gone. This actually is sent by the // browser process to itself, but keeps the interface cleaner. - IPC_MESSAGE_ROUTED0(ViewHostMsg_RenderViewGone) + IPC_MESSAGE_ROUTED2(ViewHostMsg_RenderViewGone, + int, /* this really is base::TerminationStatus */ + int /* exit_code */) // Sent by the renderer process to request that the browser close the view. // This corresponds to the window.close() API, and the browser may ignore diff --git a/chrome/common/result_codes.h b/chrome/common/result_codes.h index 6625cb0..94ba503 100644 --- a/chrome/common/result_codes.h +++ b/chrome/common/result_codes.h @@ -21,9 +21,9 @@ class ResultCodes { public: enum ExitCode { - NORMAL_EXIT = base::PROCESS_END_NORMAL_TERMINATION, - TASKMAN_KILL = base::PROCESS_END_KILLED_BY_USER, - HUNG = base::PROCESS_END_PROCESS_WAS_HUNG, + NORMAL_EXIT = base::TERMINATION_STATUS_NORMAL_TERMINATION, + TASKMAN_KILL = base::TERMINATION_STATUS_PROCESS_WAS_KILLED, + HUNG = base::TERMINATION_STATUS_PROCESS_WAS_HUNG, INVALID_CMDLINE_URL, // An invalid command line url was given. SBOX_INIT_FAILED, // The sandbox could not be initialized. GOOGLE_UPDATE_INIT_FAILED, // The Google Update client stub init failed. |