Index: chrome/browser/renderer_host/browser_render_process_host.cc |
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc |
index 0e25051df9175eeb227be0641f2c00c136934c8e..c7c01f842d4870afea786e993dd141a03b7cbb4d 100644 |
--- a/chrome/browser/renderer_host/browser_render_process_host.cc |
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc |
@@ -668,13 +668,24 @@ void BrowserRenderProcessHost::OnChannelError() { |
DCHECK(process_.handle()); |
DCHECK(channel_.get()); |
- if (base::DidProcessCrash(process_.handle())) { |
+ bool child_exited; |
+ if (base::DidProcessCrash(&child_exited, process_.handle())) { |
NotificationService::current()->Notify( |
NotificationType::RENDERER_PROCESS_CRASHED, |
Source<RenderProcessHost>(this), NotificationService::NoDetails()); |
} |
- process_.Close(); |
+ // 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 |
+ // ~BrowserRenderProcessHost via ProcessWatcher. So we can't close the handle |
+ // here. |
+ // |
+ // This is moot on Windows where |child_exited| will always be true. |
+ if (child_exited) |
+ process_.Close(); |
+ |
channel_.reset(); |
// This process should detach all the listeners, causing the object to be |