summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Graham <scottmg@chromium.org>2015-12-03 19:23:29 -0800
committerScott Graham <scottmg@chromium.org>2015-12-04 03:26:09 +0000
commitcae6b0ec5d499bb49dc0591087b8bc16b4ae339a (patch)
tree351f900cc614838e3bdfcafe689b7eb2a84d0ad0
parent3b65a5304ae4663ec5fa8f490cbe08cd669f5989 (diff)
downloadchromium_src-cae6b0ec5d499bb49dc0591087b8bc16b4ae339a.zip
chromium_src-cae6b0ec5d499bb49dc0591087b8bc16b4ae339a.tar.gz
chromium_src-cae6b0ec5d499bb49dc0591087b8bc16b4ae339a.tar.bz2
win: Move Crashpad all into chrome.exe
This initializes Crashpad much earlier at the beginning of WinMain, which captures early crashes about as well as we can. It also removes all Crashpad code from chrome.dll and chrome_child.dll. The cost for this is one thunk function that's looked up in crash_upload_list_crashpad.cc to get back into chrome.exe (for its global ChromeCrashReporterClient). That part is a little icky, but I think it's worthwhile to get initialization before anything in the DLL is run. R=cpu@chromium.org, mark@chromium.org BUG=546288, 561653, 564328 Review URL: https://codereview.chromium.org/1481703002 . Cr-Commit-Position: refs/heads/master@{#363097}
-rw-r--r--chrome/BUILD.gn2
-rw-r--r--chrome/app/chrome_crash_reporter_client.cc18
-rw-r--r--chrome/app/chrome_exe_main_win.cc90
-rw-r--r--chrome/app/chrome_main_delegate.cc14
-rw-r--r--chrome/browser/BUILD.gn2
-rw-r--r--chrome/browser/crash_upload_list.cc8
-rw-r--r--chrome/browser/crash_upload_list_crashpad.cc40
-rw-r--r--chrome/browser/crash_upload_list_crashpad.h4
-rw-r--r--chrome/browser_tests.isolate1
-rw-r--r--chrome/chrome_dll.gypi8
-rw-r--r--chrome/chrome_exe.gypi9
-rw-r--r--chrome/chrome_tests_unit.gypi1
-rw-r--r--chrome/common/chrome_paths.cc2
-rw-r--r--chrome/sync_integration_tests.isolate1
-rw-r--r--chrome/test/BUILD.gn6
-rw-r--r--chrome/test/base/chrome_test_launcher.cc16
-rw-r--r--components/crash/content/app/crashpad_win.cc3
17 files changed, 152 insertions, 73 deletions
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index efb7dc6..462e318 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -405,8 +405,6 @@ if (is_mac || is_win) {
shared_library("chrome_child") {
sources = [
- "app/chrome_crash_reporter_client.cc",
- "app/chrome_crash_reporter_client.h",
"app/chrome_main.cc",
"app/chrome_main_delegate.cc",
"app/chrome_main_delegate.h",
diff --git a/chrome/app/chrome_crash_reporter_client.cc b/chrome/app/chrome_crash_reporter_client.cc
index 2663a08..4cac4f1 100644
--- a/chrome/app/chrome_crash_reporter_client.cc
+++ b/chrome/app/chrome_crash_reporter_client.cc
@@ -16,6 +16,7 @@
#include "chrome/common/chrome_result_codes.h"
#include "chrome/common/crash_keys.h"
#include "chrome/common/env_vars.h"
+#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/google_update_settings.h"
#include "content/public/common/content_switches.h"
@@ -278,6 +279,22 @@ base::FilePath ChromeCrashReporterClient::GetReporterLogFilename() {
bool ChromeCrashReporterClient::GetCrashDumpLocation(
base::FilePath* crash_dir) {
+#if defined(OS_WIN)
+ // In order to be able to start crash handling very early, we do not rely on
+ // chrome's PathService entries (for DIR_CRASH_DUMPS) being available on
+ // Windows. See https://crbug.com/564398.
+ base::FilePath result;
+ if (!PathService::Get(base::DIR_LOCAL_APP_DATA, &result))
+ return false;
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ result = result.Append(dist->GetInstallSubDir());
+ // TODO(scottmg): Consider supporting --user-data-dir. See
+ // https://crbug.com/565446.
+ result = result.Append(chrome::kUserDataDirname);
+ result = result.Append(FILE_PATH_LITERAL("Crashpad"));
+ *crash_dir = result;
+ return true;
+#else
// By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate
// location to write breakpad crash dumps can be set.
scoped_ptr<base::Environment> env(base::Environment::Create());
@@ -289,6 +306,7 @@ bool ChromeCrashReporterClient::GetCrashDumpLocation(
}
return PathService::Get(chrome::DIR_CRASH_DUMPS, crash_dir);
+#endif
}
size_t ChromeCrashReporterClient::RegisterCrashKeys() {
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc
index cf91743..c052283 100644
--- a/chrome/app/chrome_exe_main_win.cc
+++ b/chrome/app/chrome_exe_main_win.cc
@@ -13,16 +13,20 @@
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/win/windows_version.h"
+#include "chrome/app/chrome_crash_reporter_client.h"
#include "chrome/app/main_dll_loader_win.h"
#include "chrome/browser/chrome_process_finder_win.h"
#include "chrome/browser/policy/policy_path_parser.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome_elf/chrome_elf_main.h"
+#include "components/crash/content/app/crash_reporter_client.h"
+#include "components/crash/content/app/crashpad.h"
#include "components/startup_metric_utils/browser/startup_metric_utils.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
@@ -30,6 +34,13 @@
#include "ui/gfx/win/dpi.h"
namespace {
+
+base::LazyInstance<ChromeCrashReporterClient>::Leaky g_chrome_crash_client =
+ LAZY_INSTANCE_INITIALIZER;
+
+base::LazyInstance<std::vector<crash_reporter::UploadedReport>>::Leaky
+ g_uploaded_reports = LAZY_INSTANCE_INITIALIZER;
+
// List of switches that it's safe to rendezvous early with. Fast start should
// not be done if a command line contains a switch not in this set.
// Note this is currently stored as a list of two because it's probably faster
@@ -125,46 +136,61 @@ void SwitchToLFHeap() {
}
}
-bool RunAsCrashpadHandler(wchar_t* command_line, int* rc) {
- const base::CommandLine cmdline = base::CommandLine::FromString(command_line);
- if (cmdline.GetSwitchValueASCII(switches::kProcessType) ==
- switches::kCrashpadHandler) {
- std::vector<base::string16> argv = cmdline.argv();
- base::string16 process_type =
- L"--" + base::UTF8ToUTF16(switches::kProcessType) + L"=";
- argv.erase(std::remove_if(argv.begin(), argv.end(),
- [&process_type](const base::string16& str) {
- return str.compare(0, process_type.size(),
- process_type) == 0;
- }),
- argv.end());
-
- scoped_ptr<char* []> argv_as_utf8(new char*[argv.size() + 1]);
- std::vector<std::string> storage;
- storage.reserve(argv.size());
- for (size_t i = 0; i < argv.size(); ++i) {
- storage.push_back(base::UTF16ToUTF8(argv[i]));
- argv_as_utf8[i] = &storage[i][0];
- }
- argv_as_utf8[argv.size()] = nullptr;
- *rc = crashpad::HandlerMain(static_cast<int>(argv.size()),
- argv_as_utf8.get());
- return true;
+int RunAsCrashpadHandler(const base::CommandLine& command_line) {
+ std::vector<base::string16> argv = command_line.argv();
+ base::string16 process_type =
+ L"--" + base::UTF8ToUTF16(switches::kProcessType) + L"=";
+ argv.erase(std::remove_if(argv.begin(), argv.end(),
+ [&process_type](const base::string16& str) {
+ return str.compare(0, process_type.size(),
+ process_type) == 0;
+ }),
+ argv.end());
+
+ scoped_ptr<char* []> argv_as_utf8(new char*[argv.size() + 1]);
+ std::vector<std::string> storage;
+ storage.reserve(argv.size());
+ for (size_t i = 0; i < argv.size(); ++i) {
+ storage.push_back(base::UTF16ToUTF8(argv[i]));
+ argv_as_utf8[i] = &storage[i][0];
}
- return false;
+ argv_as_utf8[argv.size()] = nullptr;
+ return crashpad::HandlerMain(static_cast<int>(argv.size()),
+ argv_as_utf8.get());
}
} // namespace
+// This helper is looked up in the browser to retrieve the crash reports. See
+// CrashUploadListCrashpad. Note that we do not pass an std::vector here,
+// because we do not want to allocate/free in different modules. The returned
+// pointer is read-only.
+extern "C" __declspec(dllexport) void GetUploadedReportsImpl(
+ const crash_reporter::UploadedReport** reports,
+ size_t* report_count) {
+ crash_reporter::GetUploadedReports(g_uploaded_reports.Pointer());
+ *reports = g_uploaded_reports.Pointer()->data();
+ *report_count = g_uploaded_reports.Pointer()->size();
+}
+
#if !defined(WIN_CONSOLE_APP)
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) {
#else
int main() {
- HINSTANCE instance = GetModuleHandle(NULL);
+ HINSTANCE instance = GetModuleHandle(nullptr);
#endif
- int rc;
- if (RunAsCrashpadHandler(GetCommandLine(), &rc))
- return rc;
+ // Initialize the CommandLine singleton from the environment.
+ base::CommandLine::Init(0, nullptr);
+
+ std::string process_type =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kProcessType);
+
+ if (process_type == switches::kCrashpadHandler)
+ return RunAsCrashpadHandler(*base::CommandLine::ForCurrentProcess());
+
+ crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer());
+ crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
SwitchToLFHeap();
@@ -173,8 +199,6 @@ int main() {
// Signal Chrome Elf that Chrome has begun to start.
SignalChromeElf();
- // Initialize the commandline singleton from the environment.
- base::CommandLine::Init(0, NULL);
// The exit manager is in charge of calling the dtors of singletons.
base::AtExitManager exit_manager;
@@ -190,7 +214,7 @@ int main() {
// Load and launch the chrome dll. *Everything* happens inside.
VLOG(1) << "About to load main DLL.";
MainDllLoader* loader = MakeMainDllLoader();
- rc = loader->Launch(instance);
+ int rc = loader->Launch(instance);
loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded();
delete loader;
return rc;
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 2d8b395..112f393 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -146,7 +146,7 @@ base::LazyInstance<ChromeContentBrowserClient> g_chrome_content_browser_client =
LAZY_INSTANCE_INITIALIZER;
#endif
-#if defined(OS_POSIX) || defined(OS_WIN)
+#if defined(OS_POSIX)
base::LazyInstance<ChromeCrashReporterClient>::Leaky g_chrome_crash_client =
LAZY_INSTANCE_INITIALIZER;
#endif
@@ -665,7 +665,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
std::string process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
-#if defined(OS_POSIX) || defined(OS_WIN)
+#if defined(OS_POSIX)
crash_reporter::SetCrashReporterClient(g_chrome_crash_client.Pointer());
#endif
@@ -680,16 +680,6 @@ void ChromeMainDelegate::PreSandboxStartup() {
#endif
#if defined(OS_WIN)
- // TODO(scottmg): It would be nice to do this earlier to catch early crashes,
- // perhaps as early as WinMain in chrome.exe. This would require some code
- // restructuring to have paths and command lines set up, and also to handle
- // having some of the code live in chrome.exe, while having the database be
- // accessed by browser code in chrome.dll (to get a list of uploaded crashes
- // for chrome://crashes).
- crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
-#endif // OS_WIN
-
-#if defined(OS_WIN)
child_process_logging::Init();
#endif
#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 22dc1a5..d3e319e 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -622,7 +622,7 @@ source_set("browser") {
} else {
sources -= [ "password_manager/password_store_x.cc" ]
}
- if ((is_posix && !is_mac && !is_ios) || is_win) {
+ if (is_posix && !is_mac && !is_ios) {
sources += [
"//chrome/app/chrome_crash_reporter_client.cc",
"//chrome/app/chrome_crash_reporter_client.h",
diff --git a/chrome/browser/crash_upload_list.cc b/chrome/browser/crash_upload_list.cc
index 9e30d84..95aa101 100644
--- a/chrome/browser/crash_upload_list.cc
+++ b/chrome/browser/crash_upload_list.cc
@@ -17,14 +17,14 @@
scoped_refptr<CrashUploadList> CreateCrashUploadList(
UploadList::Delegate* delegate) {
+#if defined(OS_MACOSX) || defined(OS_WIN)
+ return new CrashUploadListCrashpad(delegate,
+ content::BrowserThread::GetBlockingPool());
+#else
base::FilePath crash_dir_path;
PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dir_path);
base::FilePath upload_log_path =
crash_dir_path.AppendASCII(CrashUploadList::kReporterLogFilename);
-#if defined(OS_MACOSX) || defined(OS_WIN)
- return new CrashUploadListCrashpad(delegate, upload_log_path,
- content::BrowserThread::GetBlockingPool());
-#else
return new CrashUploadList(delegate, upload_log_path,
content::BrowserThread::GetBlockingPool());
#endif
diff --git a/chrome/browser/crash_upload_list_crashpad.cc b/chrome/browser/crash_upload_list_crashpad.cc
index a2a4bbd..6d2ee26 100644
--- a/chrome/browser/crash_upload_list_crashpad.cc
+++ b/chrome/browser/crash_upload_list_crashpad.cc
@@ -6,19 +6,55 @@
#include "base/threading/sequenced_worker_pool.h"
#include "base/time/time.h"
+#include "chrome/common/chrome_constants.h"
#include "components/crash/content/app/crashpad.h"
+namespace {
+
+#if defined(OS_WIN)
+typedef void (*GetUploadedReportsPointer)(
+ const crash_reporter::UploadedReport** reports,
+ size_t* report_count);
+
+void GetUploadedReportsThunk(
+ std::vector<crash_reporter::UploadedReport>* uploaded_reports) {
+ static GetUploadedReportsPointer get_uploaded_reports = []() {
+ HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
+ return reinterpret_cast<GetUploadedReportsPointer>(
+ exe_module ? GetProcAddress(exe_module, "GetUploadedReportsImpl")
+ : nullptr);
+ }();
+
+ if (get_uploaded_reports) {
+ const crash_reporter::UploadedReport* reports;
+ size_t report_count;
+ get_uploaded_reports(&reports, &report_count);
+ *uploaded_reports = std::vector<crash_reporter::UploadedReport>(
+ reports, reports + report_count);
+ }
+}
+#endif // OS_WIN
+
+} // namespace
+
CrashUploadListCrashpad::CrashUploadListCrashpad(
Delegate* delegate,
- const base::FilePath& upload_log_path,
const scoped_refptr<base::SequencedWorkerPool>& worker_pool)
- : CrashUploadList(delegate, upload_log_path, worker_pool) {}
+ : CrashUploadList(delegate, base::FilePath(), worker_pool) {}
CrashUploadListCrashpad::~CrashUploadListCrashpad() {}
void CrashUploadListCrashpad::LoadUploadList() {
std::vector<crash_reporter::UploadedReport> uploaded_reports;
+#if defined(OS_WIN)
+ // On Windows, we only link crash client into chrome.exe (not the dlls), and
+ // it does the registration. That means the global that holds the crash report
+ // database lives in the .exe, so we need to grab a pointer to a helper in the
+ // exe to get our uploaded reports list.
+ GetUploadedReportsThunk(&uploaded_reports);
+#else
crash_reporter::GetUploadedReports(&uploaded_reports);
+#endif
ClearUploads();
for (const crash_reporter::UploadedReport& uploaded_report :
diff --git a/chrome/browser/crash_upload_list_crashpad.h b/chrome/browser/crash_upload_list_crashpad.h
index d884640..2f8281b 100644
--- a/chrome/browser/crash_upload_list_crashpad.h
+++ b/chrome/browser/crash_upload_list_crashpad.h
@@ -17,12 +17,8 @@ class SequencedWorkerPool;
// Crashpad database.
class CrashUploadListCrashpad : public CrashUploadList {
public:
- // The |upload_log_path| argument is unused. It is only accepted because the
- // base class constructor requires it, although it is entirely unused with
- // LoadUploadList() being overridden.
CrashUploadListCrashpad(
Delegate* delegate,
- const base::FilePath& upload_log_path,
const scoped_refptr<base::SequencedWorkerPool>& worker_pool);
protected:
diff --git a/chrome/browser_tests.isolate b/chrome/browser_tests.isolate
index 66fbba0..d90c90a 100644
--- a/chrome/browser_tests.isolate
+++ b/chrome/browser_tests.isolate
@@ -205,6 +205,7 @@
'<(PRODUCT_DIR)/chrome_elf.dll',
'<(PRODUCT_DIR)/clearkeycdm.dll',
'<(PRODUCT_DIR)/clearkeycdmadapter.dll',
+ '<(PRODUCT_DIR)/crashpad_handler.exe',
'<(PRODUCT_DIR)/plugins/',
'<(PRODUCT_DIR)/power_saver_test_plugin.dll',
'<(PRODUCT_DIR)/ppapi_tests.dll',
diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi
index 52a7401..c873e52 100644
--- a/chrome/chrome_dll.gypi
+++ b/chrome/chrome_dll.gypi
@@ -123,9 +123,7 @@
],
'dependencies': [
'<@(chromium_browser_dependencies)',
- '../components/components.gyp:crash_component',
'../content/content.gyp:content_app_browser',
- '../third_party/crashpad/crashpad/handler/handler.gyp:crashpad_handler',
],
'conditions': [
['OS=="win"', {
@@ -165,8 +163,6 @@
],
'sources': [
'app/chrome_dll.rc',
- 'app/chrome_crash_reporter_client.cc',
- 'app/chrome_crash_reporter_client.h',
# ETW Manifest.
'<(SHARED_INTERMEDIATE_DIR)/base/trace_event/etw_manifest/chrome_events_win.rc',
@@ -304,6 +300,7 @@
'dependencies': [
'../components/components.gyp:crash_component',
'../components/components.gyp:policy',
+ '../third_party/crashpad/crashpad/handler/handler.gyp:crashpad_handler',
],
'sources': [
'app/chrome_crash_reporter_client.cc',
@@ -355,7 +352,6 @@
'dependencies': [
'<@(chromium_child_dependencies)',
'../components/components.gyp:browser_watcher_client',
- '../components/components.gyp:crash_component',
'../content/content.gyp:content_app_child',
'chrome_version_resources',
'policy_path_parser',
@@ -365,8 +361,6 @@
],
'sources': [
'<(SHARED_INTERMEDIATE_DIR)/chrome_version/chrome_dll_version.rc',
- 'app/chrome_crash_reporter_client.cc',
- 'app/chrome_crash_reporter_client.h',
'app/chrome_main.cc',
'app/chrome_main_delegate.cc',
'app/chrome_main_delegate.h',
diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi
index 4527469..9117c87e6 100644
--- a/chrome/chrome_exe.gypi
+++ b/chrome/chrome_exe.gypi
@@ -71,10 +71,10 @@
'app/chrome_watcher_client_win.h',
'app/chrome_watcher_command_line_win.cc',
'app/chrome_watcher_command_line_win.h',
- 'app/main_dll_loader_win.cc',
- 'app/main_dll_loader_win.h',
'app/kasko_client.cc',
'app/kasko_client.h',
+ 'app/main_dll_loader_win.cc',
+ 'app/main_dll_loader_win.h',
'app/signature_validator_win.cc',
'app/signature_validator_win.h',
],
@@ -105,8 +105,13 @@
'chrome_watcher',
'chrome_watcher_client',
'../components/components.gyp:browser_watcher_client',
+ '../components/components.gyp:crash_component',
'../third_party/crashpad/crashpad/handler/handler.gyp:crashpad_handler_lib',
],
+ 'sources': [
+ 'app/chrome_crash_reporter_client.cc',
+ 'app/chrome_crash_reporter_client.h',
+ ],
'conditions': [
['kasko==1', {
'dependencies': [
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index c5cdcef..4cc1d73 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -2071,6 +2071,7 @@
],
'dependencies': [
'../components/components.gyp:crash_component',
+ '../third_party/crashpad/crashpad/handler/handler.gyp:crashpad_handler',
'../win8/win8.gyp:test_registrar_constants',
'../win8/win8.gyp:test_support_win8',
],
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc
index 66c7bf2..4c19077 100644
--- a/chrome/common/chrome_paths.cc
+++ b/chrome/common/chrome_paths.cc
@@ -207,6 +207,8 @@ bool PathProvider(int key, base::FilePath* result) {
// directory. This avoids the problem of having to re-initialize the
// exception handler after parsing command line options, which may
// override the location of the app's profile directory.
+ // TODO(scottmg): Consider supporting --user-data-dir. See
+ // https://crbug.com/565446.
if (!GetDefaultUserDataDirectory(&cur))
return false;
#endif
diff --git a/chrome/sync_integration_tests.isolate b/chrome/sync_integration_tests.isolate
index 295da53..4bb4ad6 100644
--- a/chrome/sync_integration_tests.isolate
+++ b/chrome/sync_integration_tests.isolate
@@ -76,6 +76,7 @@
'variables': {
'files': [
'<(PRODUCT_DIR)/chrome_elf.dll',
+ '<(PRODUCT_DIR)/crashpad_handler.exe',
],
},
}],
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 32a0caa..2cd8714 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -197,7 +197,11 @@ source_set("test_support") {
]
}
if (is_win) {
- public_deps += [ "//third_party/wtl" ]
+ sources += [ "//chrome/app/chrome_crash_reporter_client.cc" ]
+ public_deps += [
+ "//components/crash/content/app",
+ "//third_party/wtl",
+ ]
if (use_aura) {
public_deps += [
"//win8:test_registrar_constants",
diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc
index a1b317e..6e59b80 100644
--- a/chrome/test/base/chrome_test_launcher.cc
+++ b/chrome/test/base/chrome_test_launcher.cc
@@ -19,7 +19,9 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/chrome_test_suite.h"
#include "chrome/test/base/test_switches.h"
+#include "components/crash/content/app/crashpad.h"
#include "content/public/app/content_main.h"
+#include "content/public/common/content_switches.h"
#include "content/public/test/test_launcher.h"
#include "content/public/test/test_utils.h"
#include "ui/base/test/ui_controls.h"
@@ -40,7 +42,7 @@
#include "ash/test/ui_controls_factory_ash.h"
#endif
-#if defined(OS_LINUX) || defined(OS_ANDROID)
+#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_WIN)
#include "chrome/app/chrome_crash_reporter_client.h"
#endif
@@ -112,14 +114,22 @@ int LaunchChromeTests(int default_jobs,
chrome_browser_application_mac::RegisterBrowserCrApp();
#endif
-#if defined(OS_LINUX) || defined(OS_ANDROID)
- // We leak this pointer intentionally. The breakpad client needs to outlive
+#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_WIN)
+ // We leak this pointer intentionally. The crash client needs to outlive
// all other code.
ChromeCrashReporterClient* crash_client = new ChromeCrashReporterClient();
ANNOTATE_LEAKING_OBJECT_PTR(crash_client);
crash_reporter::SetCrashReporterClient(crash_client);
#endif
+#if defined(OS_WIN)
+ base::CommandLine::Init(0, nullptr);
+ std::string process_type =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kProcessType);
+ crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
+#endif
+
ChromeTestLauncherDelegate launcher_delegate(runner);
return content::LaunchTests(&launcher_delegate, default_jobs, argc, argv);
}
diff --git a/components/crash/content/app/crashpad_win.cc b/components/crash/content/app/crashpad_win.cc
index 684366e..856ef88 100644
--- a/components/crash/content/app/crashpad_win.cc
+++ b/components/crash/content/app/crashpad_win.cc
@@ -68,8 +68,7 @@ base::FilePath PlatformCrashpadInitialization(bool initial_client,
// In test binaries, use crashpad_handler directly. Otherwise, we launch
// chrome.exe with --type=crashpad-handler.
if (exe_file.BaseName().value() != FILE_PATH_LITERAL("chrome.exe")) {
- base::FilePath exe_dir;
- CHECK(PathService::Get(base::DIR_EXE, &exe_dir));
+ base::FilePath exe_dir = exe_file.DirName();
exe_file = exe_dir.Append(FILE_PATH_LITERAL("crashpad_handler.exe"));
} else {
arguments.push_back("--type=crashpad-handler");