| OLD | NEW | 
|---|
| 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/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 | 
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 319         google_breakpad::CustomInfoEntry(L"num-views", L"N/A")); | 319         google_breakpad::CustomInfoEntry(L"num-views", L"N/A")); | 
| 320   } | 320   } | 
| 321 | 321 | 
| 322   static google_breakpad::CustomClientInfo custom_client_info; | 322   static google_breakpad::CustomClientInfo custom_client_info; | 
| 323   custom_client_info.entries = &g_custom_entries->front(); | 323   custom_client_info.entries = &g_custom_entries->front(); | 
| 324   custom_client_info.count = g_custom_entries->size(); | 324   custom_client_info.count = g_custom_entries->size(); | 
| 325 | 325 | 
| 326   return &custom_client_info; | 326   return &custom_client_info; | 
| 327 } | 327 } | 
| 328 | 328 | 
| 329 // Contains the information needed by the worker thread. | 329 // Contains the information needed by InitCrashReporterMain(). | 
| 330 struct CrashReporterInfo { | 330 struct CrashReporterInfo { | 
| 331   google_breakpad::CustomClientInfo* custom_info; | 331   google_breakpad::CustomClientInfo* custom_info; | 
| 332   std::wstring exe_path; | 332   std::wstring exe_path; | 
| 333   std::wstring process_type; | 333   std::wstring process_type; | 
| 334 }; | 334 }; | 
| 335 | 335 | 
| 336 // This callback is used when we want to get a dump without crashing the | 336 // This callback is used when we want to get a dump without crashing the | 
| 337 // process. | 337 // process. | 
| 338 bool DumpDoneCallbackWhenNoCrash(const wchar_t*, const wchar_t*, void*, | 338 bool DumpDoneCallbackWhenNoCrash(const wchar_t*, const wchar_t*, void*, | 
| 339                                  EXCEPTION_POINTERS* ex_info, | 339                                  EXCEPTION_POINTERS* ex_info, | 
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 598   base::win::RegKey hkcu_policy_key(HKEY_CURRENT_USER, | 598   base::win::RegKey hkcu_policy_key(HKEY_CURRENT_USER, | 
| 599                                     policy::kRegistryMandatorySubKey, KEY_READ); | 599                                     policy::kRegistryMandatorySubKey, KEY_READ); | 
| 600   if (hkcu_policy_key.ReadValueDW(key_name.c_str(), &value) == ERROR_SUCCESS) { | 600   if (hkcu_policy_key.ReadValueDW(key_name.c_str(), &value) == ERROR_SUCCESS) { | 
| 601     *result = value != 0; | 601     *result = value != 0; | 
| 602     return true; | 602     return true; | 
| 603   } | 603   } | 
| 604 | 604 | 
| 605   return false; | 605   return false; | 
| 606 } | 606 } | 
| 607 | 607 | 
| 608 static DWORD __stdcall InitCrashReporterThread(void* param) { | 608 // TODO(mseaborn): This function could be merged with InitCrashReporter(). | 
| 609   scoped_ptr<CrashReporterInfo> info( | 609 static void InitCrashReporterMain(CrashReporterInfo* param) { | 
| 610       reinterpret_cast<CrashReporterInfo*>(param)); | 610   scoped_ptr<CrashReporterInfo> info(param); | 
| 611 | 611 | 
| 612   bool is_per_user_install = | 612   bool is_per_user_install = | 
| 613       InstallUtil::IsPerUserInstall(info->exe_path.c_str()); | 613       InstallUtil::IsPerUserInstall(info->exe_path.c_str()); | 
| 614 | 614 | 
| 615   std::wstring channel_string; | 615   std::wstring channel_string; | 
| 616   GoogleUpdateSettings::GetChromeChannelAndModifiers(!is_per_user_install, | 616   GoogleUpdateSettings::GetChromeChannelAndModifiers(!is_per_user_install, | 
| 617                                                      &channel_string); | 617                                                      &channel_string); | 
| 618 | 618 | 
| 619   // GetCustomInfo can take a few milliseconds to get the file information, so |  | 
| 620   // we do it here so it can run in a separate thread. |  | 
| 621   info->custom_info = GetCustomInfo(info->exe_path, info->process_type, | 619   info->custom_info = GetCustomInfo(info->exe_path, info->process_type, | 
| 622                                     channel_string); | 620                                     channel_string); | 
| 623 | 621 | 
| 624   google_breakpad::ExceptionHandler::MinidumpCallback callback = NULL; | 622   google_breakpad::ExceptionHandler::MinidumpCallback callback = NULL; | 
| 625   LPTOP_LEVEL_EXCEPTION_FILTER default_filter = NULL; | 623   LPTOP_LEVEL_EXCEPTION_FILTER default_filter = NULL; | 
| 626   // We install the post-dump callback only for the browser and service | 624   // We install the post-dump callback only for the browser and service | 
| 627   // processes. It spawns a new browser/service process. | 625   // processes. It spawns a new browser/service process. | 
| 628   if (info->process_type == L"browser") { | 626   if (info->process_type == L"browser") { | 
| 629     callback = &DumpDoneCallback; | 627     callback = &DumpDoneCallback; | 
| 630     default_filter = &ChromeExceptionFilter; | 628     default_filter = &ChromeExceptionFilter; | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 662     // via policy). | 660     // via policy). | 
| 663     if (!controlled_by_policy) | 661     if (!controlled_by_policy) | 
| 664       crash_reporting_enabled = GoogleUpdateSettings::GetCollectStatsConsent(); | 662       crash_reporting_enabled = GoogleUpdateSettings::GetCollectStatsConsent(); | 
| 665 | 663 | 
| 666     if (!crash_reporting_enabled) { | 664     if (!crash_reporting_enabled) { | 
| 667       // Configuration managed or the user did not allow Google Update to send | 665       // Configuration managed or the user did not allow Google Update to send | 
| 668       // crashes, we need to use our default crash handler instead, but only | 666       // crashes, we need to use our default crash handler instead, but only | 
| 669       // for the browser/service processes. | 667       // for the browser/service processes. | 
| 670       if (default_filter) | 668       if (default_filter) | 
| 671         InitDefaultCrashCallback(default_filter); | 669         InitDefaultCrashCallback(default_filter); | 
| 672       return 0; | 670       return; | 
| 673     } | 671     } | 
| 674 | 672 | 
| 675     // Build the pipe name. It can be either: | 673     // Build the pipe name. It can be either: | 
| 676     // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18" | 674     // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18" | 
| 677     // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>" | 675     // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>" | 
| 678     std::wstring user_sid; | 676     std::wstring user_sid; | 
| 679     if (is_per_user_install) { | 677     if (is_per_user_install) { | 
| 680       if (!base::win::GetUserSidString(&user_sid)) { | 678       if (!base::win::GetUserSidString(&user_sid)) { | 
| 681         if (default_filter) | 679         if (default_filter) | 
| 682           InitDefaultCrashCallback(default_filter); | 680           InitDefaultCrashCallback(default_filter); | 
| 683         return -1; | 681         return; | 
| 684       } | 682       } | 
| 685     } else { | 683     } else { | 
| 686       user_sid = kSystemPrincipalSid; | 684       user_sid = kSystemPrincipalSid; | 
| 687     } | 685     } | 
| 688 | 686 | 
| 689     pipe_name = kGoogleUpdatePipeName; | 687     pipe_name = kGoogleUpdatePipeName; | 
| 690     pipe_name += user_sid; | 688     pipe_name += user_sid; | 
| 691   } | 689   } | 
| 692 #ifdef _WIN64 | 690 #ifdef _WIN64 | 
| 693   // The protocol for connecting to the out-of-process Breakpad crash | 691   // The protocol for connecting to the out-of-process Breakpad crash | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 731       // handlers. | 729       // handlers. | 
| 732       google_breakpad::ExceptionHandler::HANDLER_NONE, | 730       google_breakpad::ExceptionHandler::HANDLER_NONE, | 
| 733       dump_type, pipe_name.c_str(), info->custom_info); | 731       dump_type, pipe_name.c_str(), info->custom_info); | 
| 734 | 732 | 
| 735   if (g_breakpad->IsOutOfProcess()) { | 733   if (g_breakpad->IsOutOfProcess()) { | 
| 736     // Tells breakpad to handle breakpoint and single step exceptions. | 734     // Tells breakpad to handle breakpoint and single step exceptions. | 
| 737     // This might break JIT debuggers, but at least it will always | 735     // This might break JIT debuggers, but at least it will always | 
| 738     // generate a crashdump for these exceptions. | 736     // generate a crashdump for these exceptions. | 
| 739     g_breakpad->set_handle_debug_exceptions(true); | 737     g_breakpad->set_handle_debug_exceptions(true); | 
| 740   } | 738   } | 
| 741 |  | 
| 742   return 0; |  | 
| 743 } | 739 } | 
| 744 | 740 | 
| 745 void InitDefaultCrashCallback(LPTOP_LEVEL_EXCEPTION_FILTER filter) { | 741 void InitDefaultCrashCallback(LPTOP_LEVEL_EXCEPTION_FILTER filter) { | 
| 746   previous_filter = SetUnhandledExceptionFilter(filter); | 742   previous_filter = SetUnhandledExceptionFilter(filter); | 
| 747 } | 743 } | 
| 748 | 744 | 
| 749 void InitCrashReporter() { | 745 void InitCrashReporter() { | 
| 750   const CommandLine& command = *CommandLine::ForCurrentProcess(); | 746   const CommandLine& command = *CommandLine::ForCurrentProcess(); | 
| 751   if (!command.HasSwitch(switches::kDisableBreakpad)) { | 747   if (!command.HasSwitch(switches::kDisableBreakpad)) { | 
| 752     // Disable the message box for assertions. | 748     // Disable the message box for assertions. | 
| 753     _CrtSetReportMode(_CRT_ASSERT, 0); | 749     _CrtSetReportMode(_CRT_ASSERT, 0); | 
| 754 | 750 | 
| 755     // Query the custom_info now because if we do it in the thread it's going to |  | 
| 756     // fail in the sandbox. The thread will delete this object. |  | 
| 757     CrashReporterInfo* info(new CrashReporterInfo); | 751     CrashReporterInfo* info(new CrashReporterInfo); | 
| 758     info->process_type = command.GetSwitchValueNative(switches::kProcessType); | 752     info->process_type = command.GetSwitchValueNative(switches::kProcessType); | 
| 759     if (info->process_type.empty()) | 753     if (info->process_type.empty()) | 
| 760       info->process_type = L"browser"; | 754       info->process_type = L"browser"; | 
| 761 | 755 | 
| 762     wchar_t exe_path[MAX_PATH]; | 756     wchar_t exe_path[MAX_PATH]; | 
| 763     exe_path[0] = 0; | 757     exe_path[0] = 0; | 
| 764     GetModuleFileNameW(NULL, exe_path, MAX_PATH); | 758     GetModuleFileNameW(NULL, exe_path, MAX_PATH); | 
| 765     info->exe_path = exe_path; | 759     info->exe_path = exe_path; | 
| 766 | 760 | 
| 767     // If this is not the browser, we can't be sure that we will be able to | 761     InitCrashReporterMain(info); | 
| 768     // initialize the crash_handler in another thread, so we run it right away. |  | 
| 769     // This is important to keep the thread for the browser process because |  | 
| 770     // it may take some times to initialize the crash_service process.  We use |  | 
| 771     // the Windows worker pool to make better reuse of the thread. |  | 
| 772     if (info->process_type != L"browser") { |  | 
| 773       InitCrashReporterThread(info); |  | 
| 774     } else { |  | 
| 775       if (QueueUserWorkItem( |  | 
| 776               &InitCrashReporterThread, |  | 
| 777               info, |  | 
| 778               WT_EXECUTELONGFUNCTION) == 0) { |  | 
| 779         // We failed to queue to the worker pool, initialize in this thread. |  | 
| 780         InitCrashReporterThread(info); |  | 
| 781       } |  | 
| 782     } |  | 
| 783   } | 762   } | 
| 784 } | 763 } | 
| OLD | NEW | 
|---|