| Index: chrome/browser/process_singleton_win.cc
|
| diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
|
| index 2bb2b68581e222c0df07c23a401dc216534ce16a..10042578ef5d1f8cb66dcfe2a6f4db5a0f9cd505 100644
|
| --- a/chrome/browser/process_singleton_win.cc
|
| +++ b/chrome/browser/process_singleton_win.cc
|
| @@ -11,6 +11,7 @@
|
| #include "base/base_paths.h"
|
| #include "base/bind.h"
|
| #include "base/command_line.h"
|
| +#include "base/debug/activity_tracker.h"
|
| #include "base/files/file_path.h"
|
| #include "base/macros.h"
|
| #include "base/metrics/histogram_macros.h"
|
| @@ -178,6 +179,51 @@ bool DisplayShouldKillMessageBox() {
|
| chrome::MESSAGE_BOX_RESULT_NO;
|
| }
|
|
|
| +void SendRemoteProcessInteractionResultHistogram(
|
| + ProcessSingleton::RemoteProcessInteractionResult result) {
|
| + UMA_HISTOGRAM_ENUMERATION(
|
| + "Chrome.ProcessSingleton.RemoteProcessInteractionResult", result,
|
| + ProcessSingleton::REMOTE_PROCESS_INTERACTION_RESULT_COUNT);
|
| +}
|
| +
|
| +// Function was copied from Process::Terminate.
|
| +void TerminateProcessWithHistograms(const base::Process& process,
|
| + int exit_code) {
|
| + DCHECK(process.IsValid());
|
| + base::TimeTicks start_time = base::TimeTicks::Now();
|
| + bool result = (::TerminateProcess(process.Handle(), exit_code) != FALSE);
|
| + DWORD terminate_error = 0;
|
| + if (result) {
|
| + DWORD wait_error = 0;
|
| + // The process may not end immediately due to pending I/O
|
| + DWORD wait_result = ::WaitForSingleObject(process.Handle(), 60 * 1000);
|
| + if (wait_result != WAIT_OBJECT_0) {
|
| + if (wait_result == WAIT_FAILED)
|
| + wait_error = ::GetLastError();
|
| + SendRemoteProcessInteractionResultHistogram(
|
| + ProcessSingleton::TERMINATE_WAIT_TIMEOUT);
|
| + DPLOG(ERROR) << "Error waiting for process exit";
|
| + } else {
|
| + SendRemoteProcessInteractionResultHistogram(
|
| + ProcessSingleton::TERMINATE_SUCCEEDED);
|
| + }
|
| + base::debug::GlobalActivityTracker::RecordProcessExitIfEnabled(
|
| + process.Pid(), exit_code);
|
| + UMA_HISTOGRAM_TIMES("Chrome.ProcessSingleton.TerminateProcessTime",
|
| + base::TimeTicks::Now() - start_time);
|
| + UMA_HISTOGRAM_SPARSE_SLOWLY(
|
| + "Chrome.ProcessSingleton.TerminationWaitErrorCode.Windows", wait_error);
|
| + } else {
|
| + terminate_error = ::GetLastError();
|
| + SendRemoteProcessInteractionResultHistogram(
|
| + ProcessSingleton::TERMINATE_FAILED);
|
| + DPLOG(ERROR) << "Unable to terminate process";
|
| + }
|
| + UMA_HISTOGRAM_SPARSE_SLOWLY(
|
| + "Chrome.ProcessSingleton.ProcessTerminateErrorCode.Windows",
|
| + terminate_error);
|
| +}
|
| +
|
| } // namespace
|
|
|
| // Microsoft's Softricity virtualization breaks the sandbox processes.
|
| @@ -242,6 +288,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
|
| return PROCESS_NOTIFIED;
|
| case chrome::NOTIFY_FAILED:
|
| remote_window_ = NULL;
|
| + SendRemoteProcessInteractionResultHistogram(RUNNING_PROCESS_NOTIFY_ERROR);
|
| return PROCESS_NONE;
|
| case chrome::NOTIFY_WINDOW_HUNG:
|
| // Fall through and potentially terminate the hung browser.
|
| @@ -253,14 +300,13 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
|
| DWORD thread_id = ::GetWindowThreadProcessId(remote_window_, &process_id);
|
| if (!thread_id || !process_id) {
|
| remote_window_ = NULL;
|
| + SendRemoteProcessInteractionResultHistogram(REMOTE_PROCESS_NOT_FOUND);
|
| return PROCESS_NONE;
|
| }
|
|
|
| // Get a handle to the process that created the window.
|
| base::Process process = base::Process::Open(process_id);
|
|
|
| - // TODO(manzagop): capture a hang report.
|
| -
|
| // Scan for every window to find a visible one.
|
| bool visible_window = false;
|
| ::EnumThreadWindows(thread_id,
|
| @@ -272,9 +318,14 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
|
| // The user denied. Quit silently.
|
| return PROCESS_NOTIFIED;
|
| }
|
| + UMA_HISTOGRAM_ENUMERATION(
|
| + "Chrome.ProcessSingleton.RemoteHungProcessTerminateReason",
|
| + visible_window ? USER_ACCEPTED_TERMINATION : NO_VISIBLE_WINDOW_FOUND,
|
| + REMOTE_HUNG_PROCESS_TERMINATE_REASON_COUNT);
|
|
|
| // Time to take action. Kill the browser process.
|
| - process.Terminate(content::RESULT_CODE_HUNG, true);
|
| + TerminateProcessWithHistograms(process, content::RESULT_CODE_HUNG);
|
| +
|
| remote_window_ = NULL;
|
| return PROCESS_NONE;
|
| }
|
|
|