diff options
author | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-16 20:47:05 +0000 |
---|---|---|
committer | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-16 20:47:05 +0000 |
commit | 66d6c1b14349ebd40e6c7d0a6ae5ececc0695536 (patch) | |
tree | 6e54f3d3d769af9369c019d433138b52718943dd /content | |
parent | e11c8ee1b8d01092326de43f8b881efb03a7ba0c (diff) | |
download | chromium_src-66d6c1b14349ebd40e6c7d0a6ae5ececc0695536.zip chromium_src-66d6c1b14349ebd40e6c7d0a6ae5ececc0695536.tar.gz chromium_src-66d6c1b14349ebd40e6c7d0a6ae5ececc0695536.tar.bz2 |
Trying to reland r101435 : Better account crashes
original code review:
http://codereview.chromium.org/7888070
This is the renderer_host piece only. and it is passing all trybots so I am
going to land it.
TBR=jam
BUG=96059
TEST=see bug
Review URL: http://codereview.chromium.org/7919022
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101564 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/renderer_host/browser_render_process_host.cc | 57 | ||||
-rw-r--r-- | content/browser/renderer_host/browser_render_process_host.h | 21 |
2 files changed, 62 insertions, 16 deletions
diff --git a/content/browser/renderer_host/browser_render_process_host.cc b/content/browser/renderer_host/browser_render_process_host.cc index 8578251..8c3034c 100644 --- a/content/browser/renderer_host/browser_render_process_host.cc +++ b/content/browser/renderer_host/browser_render_process_host.cc @@ -93,6 +93,7 @@ #if defined(OS_WIN) #include <objbase.h> +#include "base/synchronization/waitable_event.h" #include "content/common/section_util_win.h" #endif @@ -650,7 +651,7 @@ bool BrowserRenderProcessHost::FastShutdownIfPossible() { return false; child_process_launcher_.reset(); - ProcessDied(); + ProcessDied(base::TERMINATION_STATUS_NORMAL_TERMINATION, 0, false); fast_shutdown_started_ = true; return true; } @@ -801,15 +802,6 @@ void BrowserRenderProcessHost::OnChannelConnected(int32 peer_pid) { } void BrowserRenderProcessHost::OnChannelError() { - ProcessDied(); -} - -void BrowserRenderProcessHost::ProcessDied() { - // Our child process has died. If we didn't expect it, it's a crash. - // In any case, we need to let everyone know it's gone. - // The OnChannelError notification can fire multiple times due to nested sync - // calls to a renderer. If we don't have a valid channel here it means we - // already handled the error. if (!channel_.get()) return; @@ -821,15 +813,54 @@ void BrowserRenderProcessHost::ProcessDied() { child_process_launcher_->GetChildTerminationStatus(&exit_code) : base::TERMINATION_STATUS_NORMAL_TERMINATION; +#if defined(OS_WIN) + if (!run_renderer_in_process()) { + if (status == base::TERMINATION_STATUS_STILL_RUNNING) { + HANDLE process = child_process_launcher_->GetHandle(); + child_process_watcher_.StartWatching( + new base::WaitableEvent(process), this); + return; + } + } +#endif + ProcessDied(status, exit_code, false); +} + +// Called when the renderer process handle has been signaled. +void BrowserRenderProcessHost::OnWaitableEventSignaled( + base::WaitableEvent* waitable_event) { +#if defined (OS_WIN) + DCHECK(child_process_launcher_.get()); + int exit_code = 0; + base::TerminationStatus status = + child_process_launcher_->GetChildTerminationStatus(&exit_code); + ProcessDied(status, exit_code, true); +#endif +} + +void BrowserRenderProcessHost::ProcessDied( + base::TerminationStatus status, int exit_code, bool was_alive) { + // Our child process has died. If we didn't expect it, it's a crash. + // In any case, we need to let everyone know it's gone. + // The OnChannelError notification can fire multiple times due to nested sync + // calls to a renderer. If we don't have a valid channel here it means we + // already handled the error. + if (status == base::TERMINATION_STATUS_PROCESS_CRASHED || status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION) { UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes", is_extension_process_ ? 2 : 1); - } - - if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) { + if (was_alive) { + UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashesWasAlive", + is_extension_process_ ? 2 : 1); + } + } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) { UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildKills", is_extension_process_ ? 2 : 1); + if (was_alive) { + UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildKillsWasAlive", + is_extension_process_ ? 2 : 1); + } } RendererClosedDetails details(status, exit_code, is_extension_process_); diff --git a/content/browser/renderer_host/browser_render_process_host.h b/content/browser/renderer_host/browser_render_process_host.h index 8e95b02..d209b03 100644 --- a/content/browser/renderer_host/browser_render_process_host.h +++ b/content/browser/renderer_host/browser_render_process_host.h @@ -12,6 +12,7 @@ #include "base/memory/scoped_ptr.h" #include "base/process.h" +#include "base/synchronization/waitable_event_watcher.h" #include "base/timer.h" #include "content/browser/child_process_launcher.h" #include "content/browser/renderer_host/render_process_host.h" @@ -23,6 +24,7 @@ class RenderWidgetHelper; namespace base { class SharedMemory; +class WaitableEvent; } // Implements a concrete RenderProcessHost for the browser process for talking @@ -40,7 +42,8 @@ class SharedMemory; // are correlated with IDs. This way, the Views and the corresponding ViewHosts // communicate through the two process objects. class BrowserRenderProcessHost : public RenderProcessHost, - public ChildProcessLauncher::Client { + public ChildProcessLauncher::Client, + public base::WaitableEventWatcher::Delegate { public: explicit BrowserRenderProcessHost(content::BrowserContext* browser_context); virtual ~BrowserRenderProcessHost(); @@ -76,6 +79,10 @@ class BrowserRenderProcessHost : public RenderProcessHost, // ChildProcessLauncher::Client implementation. virtual void OnProcessLaunched(); + // base::WaitableEventWatcher::Delegate implementation. + virtual void OnWaitableEventSignaled( + base::WaitableEvent* waitable_event) OVERRIDE; + private: friend class VisitRelayingRenderProcessHost; @@ -102,8 +109,11 @@ class BrowserRenderProcessHost : public RenderProcessHost, // Callers can reduce the RenderProcess' priority. void SetBackgrounded(bool backgrounded); - // Handle termination of our process. - void ProcessDied(); + // Handle termination of our process. |was_alive| indicates that when we + // tried to retrieve the exit code the process had not finished yet. + void ProcessDied(base::TerminationStatus status, + int exit_code, + bool was_alive); // The count of currently visible widgets. Since the host can be a container // for multiple widgets, it uses this count to determine when it should be @@ -150,6 +160,11 @@ class BrowserRenderProcessHost : public RenderProcessHost, // because the queued messages may have dependencies on the init messages. std::queue<IPC::Message*> queued_messages_; +#if defined(OS_WIN) + // Used to wait until the renderer dies to get an accurrate exit code. + base::WaitableEventWatcher child_process_watcher_; +#endif + DISALLOW_COPY_AND_ASSIGN(BrowserRenderProcessHost); }; |