Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(544)

Unified Diff: chrome/browser/process_singleton_win.cc

Issue 1844023002: Capture a report on failed browser rendez-vous. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Executable name check Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/process_singleton_win.cc
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index 335215680f0d1063b90260fcd4b1e7b9e39a3248..b0d52e4aeff901b653756272362fbaa0ef47937d 100644
--- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc
@@ -6,12 +6,16 @@
#include <shellapi.h>
#include <stddef.h>
+#include <winbase.h>
grt (UTC plus 2) 2016/04/05 17:22:08 change this to #include <windows.h> and move it ab
manzagop (departed) 2016/04/06 19:36:02 Done.
+
+#include <cwchar>
grt (UTC plus 2) 2016/04/05 17:22:07 why? wchar_t is a keyword. is there something else
manzagop (departed) 2016/04/06 19:36:01 Done. Dead code (was using wcscmp at one point).
#include "base/base_paths.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/macros.h"
+#include "base/path_service.h"
#include "base/process/process.h"
#include "base/process/process_info.h"
#include "base/strings/string_number_conversions.h"
@@ -26,14 +30,19 @@
#include "chrome/browser/chrome_process_finder_win.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/ui/simple_message_box.h"
+#include "chrome/chrome_watcher/kasko_util.h"
+#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/grit/chromium_strings.h"
+#include "chrome/installer/util/util_constants.h"
#include "chrome/installer/util/wmi.h"
+#include "components/version_info/version_info.h"
#include "content/public/common/result_codes.h"
#include "net/base/escape.h"
+#include "third_party/kasko/kasko_features.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/win/hwnd_util.h"
@@ -179,6 +188,64 @@ bool DisplayShouldKillMessageBox() {
chrome::MESSAGE_BOX_RESULT_NO;
}
+#if BUILDFLAG(ENABLE_KASKO)
+#if BUILDFLAG(ENABLE_KASKO_FAILED_RDV_REPORTS)
+// Capture a failed rendez-vous hang report of the other process. Kasko needs
+// the exception context to live either in the dumper of the dumpee. This
grt (UTC plus 2) 2016/04/05 17:22:07 of -> or?
manzagop (departed) 2016/04/06 19:36:01 Done.
+// means we cannot rely on kasko reporters from either browser watcher, and
+// instead spin up a new reporter.
+void SendFailedRdvReport(const base::Process& process, const DWORD thread_id) {
grt (UTC plus 2) 2016/04/05 17:22:07 remove "const"
manzagop (departed) 2016/04/06 19:36:02 Done.
+ // TODO(manzagop): add a metric for the number of captured hang reports, for
+ // comparison with uploaded count?
+
+ // Ensure the target process shares the current process' executable name. This
grt (UTC plus 2) 2016/04/05 17:22:08 nit: process's
manzagop (departed) 2016/04/06 19:36:02 Done.
+ // is to defend against races that exist in getting a Process from a window
+ // name (HWND and process id recycling).
+ // TODO(manzagop): add a metric for the number of times this does not match.
+ wchar_t exe_name_self[MAX_PATH];
+ if (GetModuleFileName(nullptr, exe_name_self, MAX_PATH) == 0)
Patrick Monette 2016/04/04 23:33:40 You can use PathService::Get(FILE_EXE) instead;
manzagop (departed) 2016/04/06 19:36:02 Done.
+ return;
+ wchar_t exe_name_other[MAX_PATH];
+ DWORD exe_name_other_len = MAX_PATH;
+ if (QueryFullProcessImageName(process.Handle(), 0, exe_name_other,
+ &exe_name_other_len) == 0) {
+ DWORD error = GetLastError();
grt (UTC plus 2) 2016/04/05 17:22:07 remove this
manzagop (departed) 2016/04/06 19:36:02 Done.
+ DPLOG(INFO) << "Failed to get executable name for other process: " << error;
grt (UTC plus 2) 2016/04/05 17:22:07 The *P* class of log functions automatically add t
manzagop (departed) 2016/04/06 19:36:02 Done.
+ return;
+ }
+ // Note: FilePath handles the complexity of path comparision (eg case).
+ if (base::FilePath(exe_name_self) != base::FilePath(exe_name_other))
Patrick Monette 2016/04/04 23:33:40 Can you move the exe name comparison to a function
Sigurður Ásgeirsson 2016/04/05 13:52:29 @grt may be familiar with cases where this compari
grt (UTC plus 2) 2016/04/05 17:22:08 We generally use base::FilePath::CompareEqualIgnor
manzagop (departed) 2016/04/06 19:36:02 Done.
manzagop (departed) 2016/04/06 19:36:02 Acknowledged.
manzagop (departed) 2016/04/06 19:36:02 False negatives are not an issue (though I have a
+ return;
+
+ // Only report on canary (or unspecified).
+ const version_info::Channel channel = chrome::GetChannel();
grt (UTC plus 2) 2016/04/05 17:22:08 consider doing this higher up in the function so t
manzagop (departed) 2016/04/06 19:36:02 Done.
+ if (channel != version_info::Channel::UNKNOWN &&
+ channel != version_info::Channel::CANARY) {
+ return;
+ }
+
+ // Initialize a reporter, capture a report and shutdown the reporter.
+ base::FilePath watcher_data_directory;
+ if (PathService::Get(chrome::DIR_WATCHER_DATA, &watcher_data_directory)) {
+ base::string16 endpoint =
+ L"chrome_kasko_rdv_" +
+ base::UintToString16(base::Process::Current().Pid());
+
+ bool launched_kasko = InitializeKaskoReporter(
+ endpoint, watcher_data_directory.value().c_str());
+ if (launched_kasko) {
+ DumpHungProcess(thread_id, installer::kChromeChannelCanary, L"failed-rdv",
+ process);
+ // We immediately request Kasko shutdown. This may block until the
+ // completion of ongoing background tasks (eg upload). If the report is
grt (UTC plus 2) 2016/04/05 17:22:08 nit: "e.g., upload"
manzagop (departed) 2016/04/06 19:36:01 Done.
+ // not uploaded by this reporter, any other Kasko reporter may upload it.
+ ShutdownKaskoReporter();
+ }
+ }
+}
+#endif // BUILDFLAG(ENABLE_KASKO_FAILED_RDV_REPORTS)
+#endif // BUILDFLAG(ENABLE_KASKO)
+
} // namespace
// Microsoft's Softricity virtualization breaks the sandbox processes.
@@ -249,15 +316,27 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
break;
}
+ // The window is hung.
grt (UTC plus 2) 2016/04/05 17:22:07 https://youtu.be/O4gqsuww6lw
manzagop (departed) 2016/04/06 19:36:02 Acknowledged?! ;)
DWORD process_id = 0;
DWORD thread_id = ::GetWindowThreadProcessId(remote_window_, &process_id);
if (!thread_id || !process_id) {
remote_window_ = NULL;
return PROCESS_NONE;
}
+
+ // Get a handle to the process that created the window.
base::Process process = base::Process::Open(process_id);
- // The window is hung. Scan for every window to find a visible one.
+ // Optionally send a failed rendez-vous report.
+ // Note: we nominate the thread that created the window as the root of the
+ // search for a hung thread.
+#if BUILDFLAG(ENABLE_KASKO)
+#if BUILDFLAG(ENABLE_KASKO_FAILED_RDV_REPORTS)
+ SendFailedRdvReport(process, thread_id);
+#endif // BUILDFLAG(ENABLE_KASKO_FAILED_RDV_REPORTS)
+#endif // BUILDFLAG(ENABLE_KASKO)
+
+ // Scan for every window to find a visible one.
bool visible_window = false;
::EnumThreadWindows(thread_id,
&BrowserWindowEnumeration,

Powered by Google App Engine
This is Rietveld 408576698