blob: 3dcd31a86441db2fd92e465572b2ab9301915093 [file] [log] [blame]
// Copyright 2013 The Goma 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 "breakpad.h"
#include <signal.h>
#include <string>
#include "client/windows/handler/exception_handler.h"
#include "glog/logging.h"
namespace {
bool g_is_crash_reporter_enabled = false;
google_breakpad::ExceptionHandler* g_breakpad = nullptr;
// TODO: revise followings when glog supports wchar_t*.
std::ostream& operator<<(std::ostream& out, const wchar_t* str) {
std::wstring wide(str);
out << std::string(wide.begin(), wide.end());
return out;
}
bool DumpCallback(const wchar_t* dump_dir,
const wchar_t* minidump_id,
void*,
EXCEPTION_POINTERS*,
MDRawAssertionInfo*,
bool succeeded) {
LOG(INFO) << "Crash Dump dir: " << dump_dir
<< " minidump_id=" << minidump_id
<< " succeeded=" << succeeded;
#ifndef GLOG_NO_ABBREVIATED_SEVERITIES
google::FlushLogFilesUnsafe(google::INFO);
#else
google::FlushLogFilesUnsafe(google::GLOG_INFO);
#endif
return succeeded;
}
void CleanUpReporter() {
g_is_crash_reporter_enabled = false;
delete g_breakpad;
}
// This function is copied from Chromium's base/win/win_util.cc.
void __cdecl ForceCrashOnSigAbort(int) {
*((volatile int*)0) = 0x1337;
}
// This function is copied from Chromium's base/win/win_util.cc.
void SetAbortBehaviorForCrashReporting() {
// Prevent CRT's abort code from prompting a dialog or trying to "report" it.
// Disabling the _CALL_REPORTFAULT behavior is important since otherwise it
// has the sideffect of clearing our exception filter, which means we
// don't get any crash.
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
// Set a SIGABRT handler for good measure. We will crash even if the default
// is left in place, however this allows us to crash earlier. And it also
// lets us crash in response to code which might directly call raise(SIGABRT)
signal(SIGABRT, ForceCrashOnSigAbort);
}
} // namespace
namespace devtools_goma {
void InitCrashReporter(const std::string& dump_output_dir) {
g_is_crash_reporter_enabled = true;
DCHECK(!g_breakpad);
std::wstring wide_dump_dir(dump_output_dir.begin(), dump_output_dir.end());
g_breakpad = new google_breakpad::ExceptionHandler(
wide_dump_dir, nullptr, DumpCallback, nullptr,
google_breakpad::ExceptionHandler::HANDLER_ALL);
SetAbortBehaviorForCrashReporting();
atexit(CleanUpReporter);
}
bool IsCrashReporterEnabled() {
return g_is_crash_reporter_enabled;
}
} // namespace devtools_goma