summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/child_process_host.cc38
-rw-r--r--chrome/browser/child_process_host.h7
-rw-r--r--chrome/browser/child_process_launcher.cc80
-rw-r--r--chrome/browser/child_process_launcher.h11
-rw-r--r--chrome/browser/metrics/metrics_service.cc18
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.cc17
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.h3
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc39
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.h1
-rw-r--r--chrome/browser/renderer_host/render_process_host.h10
-rw-r--r--chrome/browser/zygote_host_linux.cc4
-rw-r--r--chrome/browser/zygote_host_linux.h13
-rw-r--r--chrome/common/notification_type.h12
13 files changed, 80 insertions, 173 deletions
diff --git a/chrome/browser/child_process_host.cc b/chrome/browser/child_process_host.cc
index 2a828e0..0c87021 100644
--- a/chrome/browser/child_process_host.cc
+++ b/chrome/browser/child_process_host.cc
@@ -179,36 +179,23 @@ void ChildProcessHost::Notify(NotificationType type) {
ChromeThread::UI, FROM_HERE, new ChildNotificationTask(type, this));
}
-void ChildProcessHost::DetermineDidChildCrash() {
- child_process_->DetermineDidProcessCrash();
+bool ChildProcessHost::DidChildCrash() {
+ return child_process_->DidProcessCrash();
}
void ChildProcessHost::OnChildDied() {
- // Either of these paths will lead to deleting this object in
- // OnDidProcessCrashDetermined, so they should be the last calls in this
- // method.
- if (handle() != base::kNullProcessHandle) {
- // Determine whether the process crashed or not. This method will invoke
- // OnDidProcessCrashDetermined with the result. This may occur
- // asynchronously.
- DetermineDidChildCrash();
- } else {
- // We do not have a process, so it couldn't have crashed.
- OnDidProcessCrashDetermined(false);
- }
-}
-
-void ChildProcessHost::OnDidProcessCrashDetermined(bool did_crash) {
- if (did_crash) {
- OnProcessCrashed();
- // Report that this child process crashed.
- Notify(NotificationType::CHILD_PROCESS_CRASHED);
- UMA_HISTOGRAM_COUNTS("ChildProcess.Crashes", this->type());
- }
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());
+ }
// Notify in the main loop of the disconnection.
Notify(NotificationType::CHILD_PROCESS_HOST_DISCONNECTED);
}
+
delete this;
}
@@ -291,11 +278,6 @@ void ChildProcessHost::ListenerHook::OnProcessLaunched() {
host_->OnProcessLaunched();
}
-void ChildProcessHost::ListenerHook::OnDidProcessCrashDetermined(
- bool did_crash) {
- host_->OnDidProcessCrashDetermined(did_crash);
-}
-
ChildProcessHost::Iterator::Iterator()
: all_(true), type_(UNKNOWN_PROCESS) {
diff --git a/chrome/browser/child_process_host.h b/chrome/browser/child_process_host.h
index 7f0509a..e735940 100644
--- a/chrome/browser/child_process_host.h
+++ b/chrome/browser/child_process_host.h
@@ -113,7 +113,6 @@ class ChildProcessHost : public ResourceDispatcherHost::Receiver,
// ChildProcessLauncher::Client implementation.
virtual void OnProcessLaunched() {}
- virtual void OnDidProcessCrashDetermined(bool did_crash);
// Derived classes can override this to know if the process crashed.
virtual void OnProcessCrashed() {}
@@ -121,10 +120,7 @@ class ChildProcessHost : public ResourceDispatcherHost::Receiver,
bool opening_channel() { return opening_channel_; }
const std::string& channel_id() { return channel_id_; }
- // Determines whether the exited process crashed or exited normally.
- // OnDidProcessCrashDetermined method will be called with the answer,
- // possibly asynchronously.
- virtual void DetermineDidChildCrash();
+ virtual bool DidChildCrash();
// Called when the child process goes away.
virtual void OnChildDied();
@@ -144,7 +140,6 @@ class ChildProcessHost : public ResourceDispatcherHost::Receiver,
virtual void OnChannelConnected(int32 peer_pid);
virtual void OnChannelError();
virtual void OnProcessLaunched();
- virtual void OnDidProcessCrashDetermined(bool did_crash);
private:
ChildProcessHost* host_;
};
diff --git a/chrome/browser/child_process_launcher.cc b/chrome/browser/child_process_launcher.cc
index ff7a9d2..206d8a7 100644
--- a/chrome/browser/child_process_launcher.cc
+++ b/chrome/browser/child_process_launcher.cc
@@ -182,14 +182,14 @@ class ChildProcessLauncher::Context
client_thread_id_, FROM_HERE,
NewRunnableMethod(
this,
- &ChildProcessLauncher::Context::NotifyProcessLaunched,
+ &ChildProcessLauncher::Context::Notify,
#if defined(OS_LINUX)
use_zygote,
#endif
handle));
}
- void NotifyProcessLaunched(
+ void Notify(
#if defined(OS_LINUX)
bool zygote,
#endif
@@ -206,59 +206,6 @@ class ChildProcessLauncher::Context
}
}
- void DetermineDidProcessCrash() {
- DCHECK(ChromeThread::CurrentlyOn(client_thread_id_));
- base::ProcessHandle handle = process_.handle();
-#if defined(OS_LINUX)
- if (zygote_) {
- ChromeThread::PostTask(
- ChromeThread::PROCESS_LAUNCHER, FROM_HERE,
- NewRunnableMethod(this,
- &Context::DetermineDidProcessCrashInternal,
- handle));
- } else
-#endif
- {
- DetermineDidProcessCrashInternal(handle);
- }
- }
-
- void DetermineDidProcessCrashInternal(base::ProcessHandle handle) {
- bool did_crash, child_exited;
-#if defined(OS_LINUX)
- if (zygote_) {
- did_crash = Singleton<ZygoteHost>()->DidProcessCrash(handle,
- &child_exited);
- ChromeThread::PostTask(
- client_thread_id_, FROM_HERE,
- NewRunnableMethod(this,
- &Context::OnDidProcessCrashDetermined,
- child_exited, did_crash));
- } else
-#endif
- {
- did_crash = base::DidProcessCrash(&child_exited, handle);
- OnDidProcessCrashDetermined(child_exited, did_crash);
- }
- }
-
- void OnDidProcessCrashDetermined(bool child_exited, bool did_crash) {
- DCHECK(ChromeThread::CurrentlyOn(client_thread_id_));
-
- // 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
- // Terminate via ProcessWatcher. So we can't close the handle here.
- if (child_exited)
- process_.Close();
-
- if (client_)
- client_->OnDidProcessCrashDetermined(did_crash);
- // The client may have deleted us in the callback. Do not add anything
- // after this point.
- }
-
void Terminate() {
if (!process_.handle())
return;
@@ -348,8 +295,27 @@ base::ProcessHandle ChildProcessLauncher::GetHandle() {
return context_->process_.handle();
}
-void ChildProcessLauncher::DetermineDidProcessCrash() {
- context_->DetermineDidProcessCrash();
+bool ChildProcessLauncher::DidProcessCrash() {
+ bool did_crash, child_exited;
+ base::ProcessHandle handle = context_->process_.handle();
+#if defined(OS_LINUX)
+ if (context_->zygote_) {
+ did_crash = Singleton<ZygoteHost>()->DidProcessCrash(handle, &child_exited);
+ } else
+#endif
+ {
+ did_crash = base::DidProcessCrash(&child_exited, handle);
+ }
+
+ // 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
+ // Terminate via ProcessWatcher. So we can't close the handle here.
+ if (child_exited)
+ context_->process_.Close();
+
+ return did_crash;
}
void ChildProcessLauncher::SetProcessBackgrounded(bool background) {
diff --git a/chrome/browser/child_process_launcher.h b/chrome/browser/child_process_launcher.h
index 01c5d16..ce1c04d 100644
--- a/chrome/browser/child_process_launcher.h
+++ b/chrome/browser/child_process_launcher.h
@@ -21,11 +21,6 @@ class ChildProcessLauncher {
// Will be called on the thread that the ChildProcessLauncher was
// constructed on.
virtual void OnProcessLaunched() = 0;
-
- // Called as a response to DetermineDidProcessCrash on the thread that
- // the ChildProcessLauncher was constructed on. This may be called
- // during DetermineDidProcessCrash or asynchronously.
- virtual void OnDidProcessCrashDetermined(bool did_crash) = 0;
};
// Launches the process asynchronously, calling the client when the result is
@@ -51,10 +46,8 @@ class ChildProcessLauncher {
// Getter for the process handle. Only call after the process has started.
base::ProcessHandle GetHandle();
- // Determines whether the exited process crashed or exited normally.
- // The Client's OnDidProcessCrashDetermined method will be called with the
- // answer.
- void DetermineDidProcessCrash();
+ // Call this when the process exits to know if a process crashed or not.
+ bool DidProcessCrash();
// Changes whether the process runs in the background or not. Only call
// this after the process has started.
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc
index 38833a0..ad24a11 100644
--- a/chrome/browser/metrics/metrics_service.cc
+++ b/chrome/browser/metrics/metrics_service.cc
@@ -481,7 +481,7 @@ void MetricsService::SetRecording(bool enabled) {
NotificationService::AllSources());
registrar_.Add(this, NotificationType::LOAD_STOP,
NotificationService::AllSources());
- registrar_.Add(this, NotificationType::RENDERER_PROCESS_CRASHED,
+ registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSED,
NotificationService::AllSources());
registrar_.Add(this, NotificationType::RENDERER_PROCESS_HANG,
NotificationService::AllSources());
@@ -557,13 +557,17 @@ void MetricsService::Observe(NotificationType type,
LogLoadStarted();
break;
- case NotificationType::RENDERER_PROCESS_CRASHED:
+ case NotificationType::RENDERER_PROCESS_CLOSED:
{
- // The details are whether it is an extension process.
- if (*Details<bool>(details).ptr())
- LogExtensionRendererCrash();
- else
- LogRendererCrash();
+ RenderProcessHost::RendererClosedDetails* process_details =
+ Details<RenderProcessHost::RendererClosedDetails>(details).ptr();
+ if (process_details->did_crash) {
+ if (process_details->was_extension_renderer) {
+ LogExtensionRendererCrash();
+ } else {
+ LogRendererCrash();
+ }
+ }
}
break;
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
index 0310e39..2648b3e 100644
--- a/chrome/browser/nacl_host/nacl_process_host.cc
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -117,19 +117,10 @@ void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
OnProcessLaunched();
}
-void NaClProcessHost::DetermineDidChildCrash() {
- // Either of these paths will lead to deleting this object in
- // OnDidProcessCrashDetermined in ChildProcessHost, so they should be the
- // last calls in this method.
- if (running_on_wow64_) {
- bool did_crash = base::DidProcessCrash(NULL, handle());
- OnDidProcessCrashDetermined(did_crash);
- } else {
- // Determine whether the process crashed or not. This method will invoke
- // OnDidProcessCrashDetermined with the result. This may occur
- // asynchronously.
- ChildProcessHost::DetermineDidChildCrash();
- }
+bool NaClProcessHost::DidChildCrash() {
+ if (running_on_wow64_)
+ return base::DidProcessCrash(NULL, handle());
+ return ChildProcessHost::DidChildCrash();
}
void NaClProcessHost::OnChildDied() {
diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h
index b6c3313..28893fc 100644
--- a/chrome/browser/nacl_host/nacl_process_host.h
+++ b/chrome/browser/nacl_host/nacl_process_host.h
@@ -36,8 +36,7 @@ class NaClProcessHost : public ChildProcessHost {
void OnProcessLaunchedByBroker(base::ProcessHandle handle);
protected:
- // Override ChildProcessHost methods.
- virtual void DetermineDidChildCrash();
+ virtual bool DidChildCrash();
virtual void OnChildDied();
private:
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index f7fb092..fff6622 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -860,12 +860,23 @@ 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) {
+ UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes",
+ extension_process_ ? 2 : 1);
+ }
+
+ RendererClosedDetails details(did_crash, extension_process_);
NotificationService::current()->Notify(
NotificationType::RENDERER_PROCESS_CLOSED,
Source<RenderProcessHost>(this),
- NotificationService::NoDetails());
+ Details<RendererClosedDetails>(&details));
WebCacheManager::GetInstance()->Remove(id());
+ child_process_.reset();
channel_.reset();
IDMap<IPC::Channel::Listener>::iterator iter(&listeners_);
@@ -877,32 +888,6 @@ void BrowserRenderProcessHost::OnChannelError() {
ClearTransportDIBCache();
- if (child_process_.get()) {
- // Determine whether the process crashed or not. This method will invoke
- // OnDidProcessCrashDetermined with the result. This may occur
- // asynchronously.
- child_process_->DetermineDidProcessCrash();
- } else {
- // This occurs in single process mode or if fast termination happened.
- // Manually trigger OnDidProcessCrashDetermined, because we know this is
- // not a crash.
- OnDidProcessCrashDetermined(false);
- }
-}
-
-void BrowserRenderProcessHost::OnDidProcessCrashDetermined(bool did_crash) {
- child_process_.reset();
-
- if (did_crash) {
- UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes",
- extension_process_ ? 2 : 1);
-
- NotificationService::current()->Notify(
- NotificationType::RENDERER_PROCESS_CRASHED,
- Source<RenderProcessHost>(this),
- Details<bool>(&extension_process_));
- }
-
// this object is not deleted at this point and may be reused later.
// TODO(darin): clean this up
}
diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h
index 00c2a02..2a7f8b6 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.h
+++ b/chrome/browser/renderer_host/browser_render_process_host.h
@@ -100,7 +100,6 @@ class BrowserRenderProcessHost : public RenderProcessHost,
// ChildProcessLauncher::Client implementation.
virtual void OnProcessLaunched();
- virtual void OnDidProcessCrashDetermined(bool did_crash);
private:
friend class VisitRelayingRenderProcessHost;
diff --git a/chrome/browser/renderer_host/render_process_host.h b/chrome/browser/renderer_host/render_process_host.h
index 1eb9804..1ceeb42 100644
--- a/chrome/browser/renderer_host/render_process_host.h
+++ b/chrome/browser/renderer_host/render_process_host.h
@@ -46,6 +46,16 @@ class RenderProcessHost : public IPC::Channel::Sender,
TYPE_EXTENSION, // Renderer with extension privileges.
};
+ // Details for RENDERER_PROCESS_CLOSED notifications.
+ struct RendererClosedDetails {
+ RendererClosedDetails(bool did_crash, bool was_extension_renderer) {
+ this->did_crash = did_crash;
+ this->was_extension_renderer = was_extension_renderer;
+ }
+ bool did_crash;
+ bool was_extension_renderer;
+ };
+
explicit RenderProcessHost(Profile* profile);
virtual ~RenderProcessHost();
diff --git a/chrome/browser/zygote_host_linux.cc b/chrome/browser/zygote_host_linux.cc
index f28e2ad..9885234 100644
--- a/chrome/browser/zygote_host_linux.cc
+++ b/chrome/browser/zygote_host_linux.cc
@@ -19,7 +19,6 @@
#include "base/string_util.h"
#include "base/unix_domain_socket_posix.h"
-#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/renderer_host/render_sandbox_host_linux.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
@@ -194,7 +193,6 @@ void ZygoteHost::Init(const std::string& sandbox_cmd) {
pid_t ZygoteHost::ForkRenderer(
const std::vector<std::string>& argv,
const base::GlobalDescriptors::Mapping& mapping) {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::PROCESS_LAUNCHER));
DCHECK(init_);
Pickle pickle;
@@ -243,7 +241,6 @@ pid_t ZygoteHost::ForkRenderer(
}
void ZygoteHost::EnsureProcessTerminated(pid_t process) {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::PROCESS_LAUNCHER));
DCHECK(init_);
Pickle pickle;
@@ -256,7 +253,6 @@ void ZygoteHost::EnsureProcessTerminated(pid_t process) {
bool ZygoteHost::DidProcessCrash(base::ProcessHandle handle,
bool* child_exited) {
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::PROCESS_LAUNCHER));
DCHECK(init_);
Pickle pickle;
pickle.WriteInt(kCmdDidProcessCrash);
diff --git a/chrome/browser/zygote_host_linux.h b/chrome/browser/zygote_host_linux.h
index 21118d5..53485e0 100644
--- a/chrome/browser/zygote_host_linux.h
+++ b/chrome/browser/zygote_host_linux.h
@@ -26,19 +26,15 @@ class ZygoteHost {
public:
void Init(const std::string& sandbox_cmd);
- // Tries to start a renderer process. Returns its pid on success, otherwise
- // base::kNullProcessHandle. Must be called on the PROCESS_LAUNCHER
- // thread.
+ // Tries to start a renderer process. Returns its pid on success, otherwise
+ // base::kNullProcessHandle;
pid_t ForkRenderer(const std::vector<std::string>& command_line,
const base::GlobalDescriptors::Mapping& mapping);
-
- // Must be called on the PROCESS_LAUNCHER thread.
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.)
- // Must be called on the PROCESS_LAUNCHER thread.
bool DidProcessCrash(base::ProcessHandle handle, bool* child_exited);
// These are the command codes used on the wire between the browser and the
@@ -56,10 +52,7 @@ class ZygoteHost {
ZygoteHost();
~ZygoteHost();
- // The socket to the zygote, which should only be accessed on the
- // PROCESS_LAUNCHER thread.
- int control_fd_;
-
+ int control_fd_; // the socket to the zygote
pid_t pid_;
bool init_;
bool using_suid_sandbox_;
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index 7c17bc1..d2463a5 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -399,17 +399,11 @@ class NotificationType {
RENDERER_PROCESS_TERMINATED,
// Indicates that a render process was closed (meaning it exited, but the
- // RenderProcessHost might be reused). The source will be the
- // corresponding RenderProcessHost. This may get sent along with
- // RENDERER_PROCESS_TERMINATED.
+ // RenderProcessHost might be reused). The source will be the corresponding
+ // RenderProcessHost. The details will be a RendererClosedDetails struct.
+ // This may get sent along with RENDERER_PROCESS_TERMINATED.
RENDERER_PROCESS_CLOSED,
- // Indicates that a render process crashed. The source will be the
- // corresponding RenderProcessHost. The details will be a bool, indicating
- // whether the process was for an extension. This will be sent in addition
- // to RENDER_PROCESS_CLOSED.
- RENDERER_PROCESS_CRASHED,
-
// Indicates that a render process has become unresponsive for a period of
// time. The source will be the RenderWidgetHost that corresponds to the
// hung view, and no details are expected.