diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/child_process_host.cc | 38 | ||||
-rw-r--r-- | chrome/browser/child_process_host.h | 7 | ||||
-rw-r--r-- | chrome/browser/child_process_launcher.cc | 80 | ||||
-rw-r--r-- | chrome/browser/child_process_launcher.h | 11 | ||||
-rw-r--r-- | chrome/browser/metrics/metrics_service.cc | 18 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.cc | 17 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.h | 3 | ||||
-rw-r--r-- | chrome/browser/renderer_host/browser_render_process_host.cc | 39 | ||||
-rw-r--r-- | chrome/browser/renderer_host/browser_render_process_host.h | 1 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_process_host.h | 10 | ||||
-rw-r--r-- | chrome/browser/zygote_host_linux.cc | 4 | ||||
-rw-r--r-- | chrome/browser/zygote_host_linux.h | 13 | ||||
-rw-r--r-- | chrome/common/notification_type.h | 12 |
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. |