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

Side by Side 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: Check buildflag/channel, set crashkey, address race 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/BUILD.gn ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/process_singleton.h" 5 #include "chrome/browser/process_singleton.h"
6 6
7 #include <shellapi.h> 7 #include <shellapi.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include "base/base_paths.h" 10 #include "base/base_paths.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/process/process.h" 15 #include "base/process/process.h"
16 #include "base/process/process_info.h" 16 #include "base/process/process_info.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
20 #include "base/time/time.h" 20 #include "base/time/time.h"
21 #include "base/win/registry.h" 21 #include "base/win/registry.h"
22 #include "base/win/scoped_handle.h" 22 #include "base/win/scoped_handle.h"
23 #include "base/win/windows_version.h" 23 #include "base/win/windows_version.h"
24 #include "chrome/browser/browser_process.h" 24 #include "chrome/browser/browser_process.h"
25 #include "chrome/browser/browser_process_platform_part.h" 25 #include "chrome/browser/browser_process_platform_part.h"
26 #include "chrome/browser/chrome_process_finder_win.h" 26 #include "chrome/browser/chrome_process_finder_win.h"
27 #include "chrome/browser/shell_integration.h" 27 #include "chrome/browser/shell_integration.h"
28 #include "chrome/browser/ui/simple_message_box.h" 28 #include "chrome/browser/ui/simple_message_box.h"
29 #include "chrome/chrome_watcher/kasko_util.h"
30 #include "chrome/common/channel_info.h"
29 #include "chrome/common/chrome_constants.h" 31 #include "chrome/common/chrome_constants.h"
30 #include "chrome/common/chrome_paths.h" 32 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_paths_internal.h" 33 #include "chrome/common/chrome_paths_internal.h"
32 #include "chrome/common/chrome_switches.h" 34 #include "chrome/common/chrome_switches.h"
33 #include "chrome/grit/chromium_strings.h" 35 #include "chrome/grit/chromium_strings.h"
36 #include "chrome/installer/util/util_constants.h"
34 #include "chrome/installer/util/wmi.h" 37 #include "chrome/installer/util/wmi.h"
38 #include "components/version_info/version_info.h"
35 #include "content/public/common/result_codes.h" 39 #include "content/public/common/result_codes.h"
36 #include "net/base/escape.h" 40 #include "net/base/escape.h"
41 #include "third_party/kasko/kasko_features.h"
37 #include "ui/base/l10n/l10n_util.h" 42 #include "ui/base/l10n/l10n_util.h"
38 #include "ui/gfx/win/hwnd_util.h" 43 #include "ui/gfx/win/hwnd_util.h"
39 44
40 namespace { 45 namespace {
41 46
42 const char kLockfile[] = "lockfile"; 47 const char kLockfile[] = "lockfile";
43 48
44 // A helper class that acquires the given |mutex| while the AutoLockMutex is in 49 // A helper class that acquires the given |mutex| while the AutoLockMutex is in
45 // scope. 50 // scope.
46 class AutoLockMutex { 51 class AutoLockMutex {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 case chrome::NOTIFY_SUCCESS: 247 case chrome::NOTIFY_SUCCESS:
243 return PROCESS_NOTIFIED; 248 return PROCESS_NOTIFIED;
244 case chrome::NOTIFY_FAILED: 249 case chrome::NOTIFY_FAILED:
245 remote_window_ = NULL; 250 remote_window_ = NULL;
246 return PROCESS_NONE; 251 return PROCESS_NONE;
247 case chrome::NOTIFY_WINDOW_HUNG: 252 case chrome::NOTIFY_WINDOW_HUNG:
248 // Fall through and potentially terminate the hung browser. 253 // Fall through and potentially terminate the hung browser.
249 break; 254 break;
250 } 255 }
251 256
257 // The window is hung.
252 DWORD process_id = 0; 258 DWORD process_id = 0;
253 DWORD thread_id = ::GetWindowThreadProcessId(remote_window_, &process_id); 259 DWORD thread_id = ::GetWindowThreadProcessId(remote_window_, &process_id);
254 if (!thread_id || !process_id) { 260 if (!thread_id || !process_id) {
255 remote_window_ = NULL; 261 remote_window_ = NULL;
256 return PROCESS_NONE; 262 return PROCESS_NONE;
257 } 263 }
264
265 // Get a handle to the process that created the window. This is racy. It's
266 // possible the original process exited and that the process id was recycled.
267 // Double check the window is still associated with an id.
258 base::Process process = base::Process::Open(process_id); 268 base::Process process = base::Process::Open(process_id);
269 process_id = 0;
270 thread_id = ::GetWindowThreadProcessId(remote_window_, &process_id);
Sigurður Ásgeirsson 2016/04/01 17:27:17 this is still racy, as you have the same problem w
Sigurður Ásgeirsson 2016/04/01 17:27:17 It's also worth noting here that we nominate the o
manzagop (departed) 2016/04/04 21:38:37 As discussed, it's hard to avoid the issues with H
manzagop (departed) 2016/04/04 21:38:38 Done.
271 if (!thread_id || !process_id) {
272 remote_window_ = NULL;
273 return PROCESS_NONE;
274 }
275 DCHECK_EQ(process.Pid(), process_id);
259 276
260 // The window is hung. Scan for every window to find a visible one. 277 #if BUILDFLAG(ENABLE_KASKO)
278 #if BUILDFLAG(ENABLE_KASKO_FAILED_RDV_REPORTS)
279 // Capture a failed rendez-vous hang report of the other process. Kasko needs
280 // the exception context to live either in the dumper of the dumpee. This
281 // means we cannot rely on kasko reporters from either browser watcher, and
282 // instead spin up a new reporter. Note that we will exit shortly after
283 // capturing the report, meaning the report may not get uploaded by this
284 // reporter.
285 // TODO(manzagop): add a metric for the number of captured hang reports, for
286 // comparison with uploaded count?
287
288 // Only report on canary (or unspecified).
289 const version_info::Channel channel = chrome::GetChannel();
290 if (channel == version_info::Channel::UNKNOWN ||
291 channel == version_info::Channel::CANARY) {
292 base::FilePath data_base_dir;
293 chrome::GetDefaultUserDataDirectory(&data_base_dir);
294 base::string16 endpoint =
295 L"chrome_kasko_hangs_" +
296 base::UintToString16(base::Process::Current().Pid());
297
298 bool launched_kasko =
Sigurður Ásgeirsson 2016/04/01 17:27:17 it's worth adding some running commentary here, wi
manzagop (departed) 2016/04/04 21:38:37 Done.
299 InitializeKaskoReporter(endpoint, data_base_dir.value().c_str());
300 if (launched_kasko) {
301 DumpHungProcess(thread_id, installer::kChromeChannelCanary, L"failed-rdv",
302 process);
303 ShutdownKaskoReporter();
304 }
305 }
306 #endif // BUILDFLAG(ENABLE_KASKO_FAILED_RDV_REPORTS)
307 #endif // BUILDFLAG(ENABLE_KASKO)
308
309 // Scan for every window to find a visible one.
261 bool visible_window = false; 310 bool visible_window = false;
262 ::EnumThreadWindows(thread_id, 311 ::EnumThreadWindows(thread_id,
263 &BrowserWindowEnumeration, 312 &BrowserWindowEnumeration,
264 reinterpret_cast<LPARAM>(&visible_window)); 313 reinterpret_cast<LPARAM>(&visible_window));
265 314
266 // If there is a visible browser window, ask the user before killing it. 315 // If there is a visible browser window, ask the user before killing it.
267 if (visible_window && !should_kill_remote_process_callback_.Run()) { 316 if (visible_window && !should_kill_remote_process_callback_.Run()) {
268 // The user denied. Quit silently. 317 // The user denied. Quit silently.
269 return PROCESS_NOTIFIED; 318 return PROCESS_NOTIFIED;
270 } 319 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 return window_.hwnd() != NULL; 397 return window_.hwnd() != NULL;
349 } 398 }
350 399
351 void ProcessSingleton::Cleanup() { 400 void ProcessSingleton::Cleanup() {
352 } 401 }
353 402
354 void ProcessSingleton::OverrideShouldKillRemoteProcessCallbackForTesting( 403 void ProcessSingleton::OverrideShouldKillRemoteProcessCallbackForTesting(
355 const ShouldKillRemoteProcessCallback& display_dialog_callback) { 404 const ShouldKillRemoteProcessCallback& display_dialog_callback) {
356 should_kill_remote_process_callback_ = display_dialog_callback; 405 should_kill_remote_process_callback_ = display_dialog_callback;
357 } 406 }
OLDNEW
« no previous file with comments | « chrome/browser/BUILD.gn ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698