blob: e6826756136dfaa7a1320ff3879cc5025384c5e0 [file] [log] [blame]
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <windows.h>
#include <DbgHelp.h>
#include <string>
#include "chrome_frame/chrome_launcher.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"
// TODO(robertshield): Much of the crash report init code is shared with CF and
// probably Chrome too. If this pans out, consider refactoring it into a
// common lib.
namespace {
// Possible names for Pipes:
// Headless (testing) mode: "NamedPipe\ChromeCrashServices"
// System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18"
// Per-user install: "NamedPipe\GoogleCrashServices\<user SID>"
const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";
const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";
// Assume this implies headless mode and use kChromePipeName if it shows
// up in the command line.
const wchar_t kFullMemoryCrashReport[] = L"full-memory-crash-report";
const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>(
MiniDumpWithProcessThreadData | // Get PEB and TEB.
MiniDumpWithUnloadedModules | // Get unloaded modules when available.
MiniDumpWithIndirectlyReferencedMemory); // Get memory referenced by stack.
} // namespace
google_breakpad::CustomClientInfo* GetCustomInfo() {
// TODO(robertshield): Populate this with actual data.
std::wstring product(L"ChromeFrame");
std::wstring version(L"0.1.0.0");
static google_breakpad::CustomInfoEntry ver_entry(L"ver", version.c_str());
static google_breakpad::CustomInfoEntry prod_entry(L"prod", product.c_str());
static google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32");
static google_breakpad::CustomInfoEntry type_entry(L"ptype", L"chrome_frame");
static google_breakpad::CustomInfoEntry entries[] = {
ver_entry, prod_entry, plat_entry, type_entry };
static google_breakpad::CustomClientInfo custom_info = {
entries, arraysize(entries) };
return &custom_info;
}
google_breakpad::ExceptionHandler* InitializeCrashReporting(
const wchar_t* cmd_line) {
if (cmd_line == NULL) {
return NULL;
}
wchar_t temp_path[MAX_PATH + 1] = {0};
DWORD path_len = ::GetTempPath(MAX_PATH, temp_path);
std::wstring pipe_name;
if (wcsstr(cmd_line, kFullMemoryCrashReport) != NULL) {
pipe_name = kChromePipeName;
} else {
// TODO(robertshield): Figure out if we're a per-user install and connect
// to the per-user named pipe instead.
pipe_name = kGoogleUpdatePipeName;
pipe_name += kSystemPrincipalSid;
}
google_breakpad::ExceptionHandler* breakpad =
new google_breakpad::ExceptionHandler(
temp_path, NULL, NULL, NULL,
google_breakpad::ExceptionHandler::HANDLER_ALL, kLargerDumpType,
pipe_name.c_str(), GetCustomInfo());
return breakpad;
}
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, wchar_t*, int) {
const wchar_t* cmd_line = ::GetCommandLine();
google_breakpad::scoped_ptr<google_breakpad::ExceptionHandler> breakpad(
InitializeCrashReporting(cmd_line));
UINT exit_code = ERROR_FILE_NOT_FOUND;
if (chrome_launcher::SanitizeAndLaunchChrome(::GetCommandLine())) {
exit_code = ERROR_SUCCESS;
}
return exit_code;
}