// 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( 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(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", UTF8ToWide(product_name).c_str())); 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::get(); } // static CrashReporter* CrashReporter::GetInstance() { return CrashReporterWin::GetInstance(); } } // namespace crash_reporter