Explicitly stop the ExitCodeWatcher if crashpad fails to initialize
Fix for potential deadlock between crashpad and ExitCodeWatcher during
launch - Bug:1057774. In the case where we fail to fully initialize
crashpad, we need to explicitly stop the ExitCodeWatcher.
Bug: 1057774
Change-Id: I31befef2bf25477d38d78c4d136a76d3aaa3be52
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2087900
Reviewed-by: Bruce Dawson <[email protected]>
Reviewed-by: Sigurður Ásgeirsson <[email protected]>
Reviewed-by: Scott Violet <[email protected]>
Commit-Queue: Mike Rorke <[email protected]>
Cr-Commit-Position: refs/heads/master@{#747767}
diff --git a/components/browser_watcher/exit_code_watcher_win.cc b/components/browser_watcher/exit_code_watcher_win.cc
index 3948243..2e2ef77c 100644
--- a/components/browser_watcher/exit_code_watcher_win.cc
+++ b/components/browser_watcher/exit_code_watcher_win.cc
@@ -4,6 +4,8 @@
#include "components/browser_watcher/exit_code_watcher_win.h"
+#include <windows.h>
+
#include <utility>
#include "base/logging.h"
@@ -15,18 +17,19 @@
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
-#include <windows.h>
-
namespace browser_watcher {
const char kBrowserExitCodeHistogramName[] = "Stability.BrowserExitCodes";
ExitCodeWatcher::ExitCodeWatcher()
- : background_thread_("ExitCodeWatcherThread"), exit_code_(STILL_ACTIVE) {}
-
-ExitCodeWatcher::~ExitCodeWatcher() {
+ : background_thread_("ExitCodeWatcherThread"),
+ exit_code_(STILL_ACTIVE),
+ stop_watching_handle_(CreateEvent(nullptr, TRUE, FALSE, nullptr)) {
+ DCHECK(stop_watching_handle_.IsValid());
}
+ExitCodeWatcher::~ExitCodeWatcher() {}
+
bool ExitCodeWatcher::Initialize(base::Process process) {
if (!process.IsValid()) {
LOG(ERROR) << "Invalid parent handle, can't get parent process ID.";
@@ -69,13 +72,20 @@
return true;
}
-void ExitCodeWatcher::WaitForExit() {
- if (!process_.WaitForExit(&exit_code_)) {
- LOG(ERROR) << "Failed to wait for process.";
- return;
+void ExitCodeWatcher::StopWatching() {
+ if (stop_watching_handle_.IsValid()) {
+ SetEvent(stop_watching_handle_.Get());
}
+}
- WriteProcessExitCode(exit_code_);
+void ExitCodeWatcher::WaitForExit() {
+ base::Process::WaitExitStatus wait_result =
+ process_.WaitForExitOrEvent(stop_watching_handle_, &exit_code_);
+ if (wait_result == base::Process::WaitExitStatus::PROCESS_EXITED) {
+ WriteProcessExitCode(exit_code_);
+ } else if (wait_result == base::Process::WaitExitStatus::FAILED) {
+ LOG(ERROR) << "Failed to wait for process exit or stop event";
+ }
}
bool ExitCodeWatcher::WriteProcessExitCode(int exit_code) {