Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/app/breakpad_win.h" | 5 #include "chrome/app/breakpad_win.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <shellapi.h> | 8 #include <shellapi.h> |
| 9 #include <tchar.h> | 9 #include <tchar.h> |
| 10 | 10 |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/base_switches.h" | 14 #include "base/base_switches.h" |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/file_util.h" | 16 #include "base/file_util.h" |
| 17 #include "base/file_version_info.h" | 17 #include "base/file_version_info.h" |
| 18 #include "base/registry.h" | 18 #include "base/registry.h" |
| 19 #include "base/string_util.h" | 19 #include "base/string_util.h" |
| 20 #include "base/utf_string_conversions.h" | |
| 20 #include "base/win_util.h" | 21 #include "base/win_util.h" |
| 21 #include "breakpad/src/client/windows/handler/exception_handler.h" | 22 #include "breakpad/src/client/windows/handler/exception_handler.h" |
| 22 #include "chrome/app/hard_error_handler_win.h" | 23 #include "chrome/app/hard_error_handler_win.h" |
| 23 #include "chrome/common/child_process_logging.h" | 24 #include "chrome/common/child_process_logging.h" |
| 24 #include "chrome/common/env_vars.h" | 25 #include "chrome/common/env_vars.h" |
| 25 #include "chrome/common/result_codes.h" | 26 #include "chrome/common/result_codes.h" |
| 27 #include "chrome/common/policy_constants.h" | |
| 26 #include "chrome/installer/util/google_chrome_sxs_distribution.h" | 28 #include "chrome/installer/util/google_chrome_sxs_distribution.h" |
| 27 #include "chrome/installer/util/google_update_settings.h" | 29 #include "chrome/installer/util/google_update_settings.h" |
| 28 #include "chrome/installer/util/install_util.h" | 30 #include "chrome/installer/util/install_util.h" |
| 29 | 31 |
| 30 namespace { | 32 namespace { |
| 31 | 33 |
| 32 // Minidump with stacks, PEB, TEB, and unloaded module list. | 34 // Minidump with stacks, PEB, TEB, and unloaded module list. |
| 33 const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>( | 35 const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>( |
| 34 MiniDumpWithProcessThreadData | // Get PEB and TEB. | 36 MiniDumpWithProcessThreadData | // Get PEB and TEB. |
| 35 MiniDumpWithUnloadedModules); // Get unloaded modules when available. | 37 MiniDumpWithUnloadedModules); // Get unloaded modules when available. |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 378 // If the UI layout is right-to-left, we need to pass the appropriate MB_XXX | 380 // If the UI layout is right-to-left, we need to pass the appropriate MB_XXX |
| 379 // flags so that an RTL message box is displayed. | 381 // flags so that an RTL message box is displayed. |
| 380 UINT flags = MB_OKCANCEL | MB_ICONWARNING; | 382 UINT flags = MB_OKCANCEL | MB_ICONWARNING; |
| 381 if (dlg_strings[2] == ASCIIToWide(env_vars::kRtlLocale)) | 383 if (dlg_strings[2] == ASCIIToWide(env_vars::kRtlLocale)) |
| 382 flags |= MB_RIGHT | MB_RTLREADING; | 384 flags |= MB_RIGHT | MB_RTLREADING; |
| 383 | 385 |
| 384 return WrapMessageBoxWithSEH(dlg_strings[1].c_str(), dlg_strings[0].c_str(), | 386 return WrapMessageBoxWithSEH(dlg_strings[1].c_str(), dlg_strings[0].c_str(), |
| 385 flags, exit_now); | 387 flags, exit_now); |
| 386 } | 388 } |
| 387 | 389 |
| 390 // Determine whether configuration management allows loading the crash reporter. | |
| 391 // Since the configuration management infrastructure is not initialized at this | |
| 392 // point, we read the corresponding registry key directly. The return status | |
| 393 // indicates whether policy data was successfully read. If it is true, |result| | |
| 394 // contains the value set by policy. | |
| 395 static bool MetricsReportingControlledByPolicy(bool* result) { | |
| 396 std::wstring key_name = UTF8ToWide(policy::key::kMetricsReportingEnabled); | |
| 397 DWORD value; | |
| 398 RegKey hkcu_policy_key(HKEY_LOCAL_MACHINE, policy::kRegistrySubKey); | |
| 399 if (hkcu_policy_key.ReadValueDW(key_name.c_str(), &value)) { | |
| 400 *result = value != 0; | |
| 401 return true; | |
| 402 } | |
| 403 | |
| 404 RegKey hklm_policy_key(HKEY_CURRENT_USER, policy::kRegistrySubKey); | |
| 405 if (hklm_policy_key.ReadValueDW(key_name.c_str(), &value)) { | |
| 406 *result = value != 0; | |
| 407 return true; | |
| 408 } | |
| 409 | |
| 410 return false; | |
| 411 } | |
| 412 | |
| 388 static DWORD __stdcall InitCrashReporterThread(void* param) { | 413 static DWORD __stdcall InitCrashReporterThread(void* param) { |
| 389 scoped_ptr<CrashReporterInfo> info( | 414 scoped_ptr<CrashReporterInfo> info( |
| 390 reinterpret_cast<CrashReporterInfo*>(param)); | 415 reinterpret_cast<CrashReporterInfo*>(param)); |
| 391 | 416 |
| 392 // GetCustomInfo can take a few milliseconds to get the file information, so | 417 // GetCustomInfo can take a few milliseconds to get the file information, so |
| 393 // we do it here so it can run in a separate thread. | 418 // we do it here so it can run in a separate thread. |
| 394 info->custom_info = GetCustomInfo(info->dll_path, info->process_type); | 419 info->custom_info = GetCustomInfo(info->dll_path, info->process_type); |
| 395 | 420 |
| 396 google_breakpad::ExceptionHandler::MinidumpCallback callback = NULL; | 421 google_breakpad::ExceptionHandler::MinidumpCallback callback = NULL; |
| 397 if (info->process_type == L"browser") { | 422 if (info->process_type == L"browser") { |
| 398 // We install the post-dump callback only for the browser process. It | 423 // We install the post-dump callback only for the browser process. It |
| 399 // spawns a new browser process. | 424 // spawns a new browser process. |
| 400 callback = &DumpDoneCallback; | 425 callback = &DumpDoneCallback; |
| 401 } | 426 } |
| 402 | 427 |
| 428 // Check whether configuration management controls crash reporting. | |
| 429 bool crash_reporting_enabled = true; | |
| 430 bool controlled_by_policy = | |
| 431 MetricsReportingControlledByPolicy(&crash_reporting_enabled); | |
| 432 | |
| 403 const CommandLine& command = *CommandLine::ForCurrentProcess(); | 433 const CommandLine& command = *CommandLine::ForCurrentProcess(); |
| 404 bool use_crash_service = command.HasSwitch(switches::kNoErrorDialogs) || | 434 bool use_crash_service = !controlled_by_policy && |
|
nsylvain
2010/07/30 17:12:49
I'm not sure when/how the registry value is going
Mattias Nissler (ping if slow)
2010/07/30 18:14:06
The registry value is the hook administrators use
| |
| 405 GetEnvironmentVariable(ASCIIToWide(env_vars::kHeadless).c_str(), NULL, 0); | 435 ((command.HasSwitch(switches::kNoErrorDialogs) || |
| 436 GetEnvironmentVariable( | |
| 437 ASCIIToWide(env_vars::kHeadless).c_str(), NULL, 0))); | |
| 406 bool is_per_user_install = | 438 bool is_per_user_install = |
| 407 InstallUtil::IsPerUserInstall(info->dll_path.c_str()); | 439 InstallUtil::IsPerUserInstall(info->dll_path.c_str()); |
| 408 | 440 |
| 409 std::wstring pipe_name; | 441 std::wstring pipe_name; |
| 410 if (use_crash_service) { | 442 if (use_crash_service) { |
| 411 // Crash reporting is done by crash_service.exe. | 443 // Crash reporting is done by crash_service.exe. |
| 412 pipe_name = kChromePipeName; | 444 pipe_name = kChromePipeName; |
| 413 } else { | 445 } else { |
| 414 // We want to use the Google Update crash reporting. We need to check if the | 446 // We want to use the Google Update crash reporting. We need to check if the |
| 415 // user allows it first. | 447 // user allows it first (in case the administrator didn't already decide |
| 416 if (!GoogleUpdateSettings::GetCollectStatsConsent()) { | 448 // via policy). |
| 417 // The user did not allow Google Update to send crashes, we need to use | 449 if (!controlled_by_policy) |
| 418 // our default crash handler instead, but only for the browser process. | 450 crash_reporting_enabled = GoogleUpdateSettings::GetCollectStatsConsent(); |
| 451 | |
| 452 LOG(ERROR) << "crash reporting enabled " << crash_reporting_enabled; | |
| 453 | |
| 454 if (!crash_reporting_enabled) { | |
| 455 // Configuration managed or the user did not allow Google Update to send | |
| 456 // crashes, we need to use our default crash handler instead, but only | |
| 457 // for the browser process. | |
| 419 if (callback) | 458 if (callback) |
| 420 InitDefaultCrashCallback(); | 459 InitDefaultCrashCallback(); |
| 421 return 0; | 460 return 0; |
| 422 } | 461 } |
| 423 | 462 |
| 424 // Build the pipe name. It can be either: | 463 // Build the pipe name. It can be either: |
| 425 // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18" | 464 // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18" |
| 426 // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>" | 465 // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>" |
| 427 std::wstring user_sid; | 466 std::wstring user_sid; |
| 428 if (is_per_user_install) { | 467 if (is_per_user_install) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 506 if (QueueUserWorkItem( | 545 if (QueueUserWorkItem( |
| 507 &InitCrashReporterThread, | 546 &InitCrashReporterThread, |
| 508 info, | 547 info, |
| 509 WT_EXECUTELONGFUNCTION) == 0) { | 548 WT_EXECUTELONGFUNCTION) == 0) { |
| 510 // We failed to queue to the worker pool, initialize in this thread. | 549 // We failed to queue to the worker pool, initialize in this thread. |
| 511 InitCrashReporterThread(info); | 550 InitCrashReporterThread(info); |
| 512 } | 551 } |
| 513 } | 552 } |
| 514 } | 553 } |
| 515 } | 554 } |
| OLD | NEW |