electron/common/crash_reporter/crash_reporter_win.cc

129 lines
4.2 KiB
C++

// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "common/crash_reporter/crash_reporter_win.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
namespace crash_reporter {
namespace {
// Minidump with stacks, PEB, TEB, and unloaded module list.
const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>(
MiniDumpWithProcessThreadData | // Get PEB and TEB.
MiniDumpWithUnloadedModules); // Get unloaded modules when available.
const wchar_t kPipeNameFormat[] = L"\\\\.\\pipe\\$1 Crash Service";
} // namespace
CrashReporterWin::CrashReporterWin() {
}
CrashReporterWin::~CrashReporterWin() {
}
void CrashReporterWin::InitBreakpad(const std::string& product_name,
const std::string& version,
const std::string& company_name,
const std::string& submit_url,
bool auto_submit,
bool skip_system_crash_handler) {
skip_system_crash_handler_ = skip_system_crash_handler;
base::FilePath temp_dir;
if (!file_util::GetTempDir(&temp_dir)) {
LOG(ERROR) << "Cannot get temp directory";
return;
}
string16 pipe_name = ReplaceStringPlaceholders(kPipeNameFormat,
UTF8ToUTF16(product_name),
NULL);
// Wait until the crash service is started.
HANDLE waiting_event =
::CreateEventW(NULL, TRUE, FALSE, L"g_atom_shell_crash_service");
if (waiting_event != INVALID_HANDLE_VALUE)
WaitForSingleObject(waiting_event, 1000);
breakpad_.reset(new google_breakpad::ExceptionHandler(
temp_dir.value(),
FilterCallback,
MinidumpCallback,
this,
google_breakpad::ExceptionHandler::HANDLER_ALL,
kSmallDumpType,
pipe_name.c_str(),
GetCustomInfo(product_name, version, company_name)));
if (!breakpad_->IsOutOfProcess())
LOG(ERROR) << "Cannot initialize out-of-process crash handler";
}
void CrashReporterWin::SetUploadParameters() {
upload_parameters_["platform"] = "win32";
}
// static
bool CrashReporterWin::FilterCallback(void* context,
EXCEPTION_POINTERS* exinfo,
MDRawAssertionInfo* assertion) {
return true;
}
// static
bool CrashReporterWin::MinidumpCallback(const wchar_t* dump_path,
const wchar_t* minidump_id,
void* context,
EXCEPTION_POINTERS* exinfo,
MDRawAssertionInfo* assertion,
bool succeeded) {
CrashReporterWin* self = static_cast<CrashReporterWin*>(context);
if (succeeded && !self->skip_system_crash_handler_)
return true;
else
return false;
}
google_breakpad::CustomClientInfo* CrashReporterWin::GetCustomInfo(
const std::string& product_name,
const std::string& version,
const std::string& company_name) {
custom_info_entries_.clear();
custom_info_entries_.reserve(2 + upload_parameters_.size());
custom_info_entries_.push_back(google_breakpad::CustomInfoEntry(
L"prod", L"Atom-Shell"));
custom_info_entries_.push_back(google_breakpad::CustomInfoEntry(
L"ver", UTF8ToWide(version).c_str()));
for (StringMap::const_iterator iter = upload_parameters_.begin();
iter != upload_parameters_.end(); ++iter) {
custom_info_entries_.push_back(google_breakpad::CustomInfoEntry(
UTF8ToWide(iter->first).c_str(),
UTF8ToWide(iter->second).c_str()));
}
custom_info_.entries = &custom_info_entries_.front();
custom_info_.count = custom_info_entries_.size();
return &custom_info_;
}
// static
CrashReporterWin* CrashReporterWin::GetInstance() {
return Singleton<CrashReporterWin>::get();
}
// static
CrashReporter* CrashReporter::GetInstance() {
return CrashReporterWin::GetInstance();
}
} // namespace crash_reporter