| Index: chrome/app/breakpad_win.cc
|
| ===================================================================
|
| --- chrome/app/breakpad_win.cc (revision 123320)
|
| +++ chrome/app/breakpad_win.cc (working copy)
|
| @@ -326,7 +326,7 @@
|
| return &custom_client_info;
|
| }
|
|
|
| -// Contains the information needed by InitCrashReporterMain().
|
| +// Contains the information needed by the worker thread.
|
| struct CrashReporterInfo {
|
| google_breakpad::CustomClientInfo* custom_info;
|
| std::wstring exe_path;
|
| @@ -605,9 +605,9 @@
|
| return false;
|
| }
|
|
|
| -// TODO(mseaborn): This function could be merged with InitCrashReporter().
|
| -static void InitCrashReporterMain(CrashReporterInfo* param) {
|
| - scoped_ptr<CrashReporterInfo> info(param);
|
| +static DWORD __stdcall InitCrashReporterThread(void* param) {
|
| + scoped_ptr<CrashReporterInfo> info(
|
| + reinterpret_cast<CrashReporterInfo*>(param));
|
|
|
| bool is_per_user_install =
|
| InstallUtil::IsPerUserInstall(info->exe_path.c_str());
|
| @@ -616,6 +616,8 @@
|
| GoogleUpdateSettings::GetChromeChannelAndModifiers(!is_per_user_install,
|
| &channel_string);
|
|
|
| + // GetCustomInfo can take a few milliseconds to get the file information, so
|
| + // we do it here so it can run in a separate thread.
|
| info->custom_info = GetCustomInfo(info->exe_path, info->process_type,
|
| channel_string);
|
|
|
| @@ -667,7 +669,7 @@
|
| // for the browser/service processes.
|
| if (default_filter)
|
| InitDefaultCrashCallback(default_filter);
|
| - return;
|
| + return 0;
|
| }
|
|
|
| // Build the pipe name. It can be either:
|
| @@ -678,7 +680,7 @@
|
| if (!base::win::GetUserSidString(&user_sid)) {
|
| if (default_filter)
|
| InitDefaultCrashCallback(default_filter);
|
| - return;
|
| + return -1;
|
| }
|
| } else {
|
| user_sid = kSystemPrincipalSid;
|
| @@ -736,6 +738,8 @@
|
| // generate a crashdump for these exceptions.
|
| g_breakpad->set_handle_debug_exceptions(true);
|
| }
|
| +
|
| + return 0;
|
| }
|
|
|
| void InitDefaultCrashCallback(LPTOP_LEVEL_EXCEPTION_FILTER filter) {
|
| @@ -748,6 +752,8 @@
|
| // Disable the message box for assertions.
|
| _CrtSetReportMode(_CRT_ASSERT, 0);
|
|
|
| + // Query the custom_info now because if we do it in the thread it's going to
|
| + // fail in the sandbox. The thread will delete this object.
|
| CrashReporterInfo* info(new CrashReporterInfo);
|
| info->process_type = command.GetSwitchValueNative(switches::kProcessType);
|
| if (info->process_type.empty())
|
| @@ -758,6 +764,21 @@
|
| GetModuleFileNameW(NULL, exe_path, MAX_PATH);
|
| info->exe_path = exe_path;
|
|
|
| - InitCrashReporterMain(info);
|
| + // If this is not the browser, we can't be sure that we will be able to
|
| + // initialize the crash_handler in another thread, so we run it right away.
|
| + // This is important to keep the thread for the browser process because
|
| + // it may take some times to initialize the crash_service process. We use
|
| + // the Windows worker pool to make better reuse of the thread.
|
| + if (info->process_type != L"browser") {
|
| + InitCrashReporterThread(info);
|
| + } else {
|
| + if (QueueUserWorkItem(
|
| + &InitCrashReporterThread,
|
| + info,
|
| + WT_EXECUTELONGFUNCTION) == 0) {
|
| + // We failed to queue to the worker pool, initialize in this thread.
|
| + InitCrashReporterThread(info);
|
| + }
|
| + }
|
| }
|
| }
|
|
|