crashpad: updated crash handler

This commit is contained in:
itsmattkc
2020-09-22 18:42:51 +10:00
parent 871bc08c12
commit cd47676043
11 changed files with 298 additions and 285 deletions
+38 -43
View File
@@ -23,75 +23,67 @@
#ifdef USE_CRASHPAD
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
#include <QDir>
#include <QMessageBox>
#include <QProcess>
#include "crashpadutils.h"
#include "filefunctions.h"
#ifdef Q_OS_WINDOWS
#ifdef OS_WIN
#include <Windows.h>
#endif
// Copied from base::FilePath to match its macro
#if defined(OS_POSIX)
// On most platforms, native pathnames are char arrays, and the encoding
// may or may not be specified. On Mac OS X, native pathnames are encoded
// in UTF-8.
#define TO_BASE_STRING_TYPE(x) x.toStdString()
#elif defined(OS_WIN)
// On Windows, for Unicode-aware applications, native pathnames are wchar_t
// arrays encoded in UTF-16.
#define TO_BASE_STRING_TYPE(x) x.toStdWString()
#endif // OS_WIN
crashpad::CrashpadClient *client;
bool ShowCrashConfirmation()
QString GenerateReportPath()
{
QString msg = QCoreApplication::translate("CrashReport",
"We're sorry, Olive has crashed. "
"Would you like to send an error report to "
"help developers fix this issue?\n\n"
"Crash reports are anonymous and only send "
"non-specific details about your computer and"
"how the crash occurred.");
return (QMessageBox::critical(nullptr,
QString(),
msg,
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes);
return QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("reports"));
}
#ifdef Q_OS_WINDOWS
base::FilePath GenerateReportPathForCrashpad()
{
return base::FilePath(QSTRING_TO_BASE_STRING(GenerateReportPath()));
}
#if defined(OS_WIN)
LONG WINAPI Win32ExceptionHandler(_EXCEPTION_POINTERS *ExceptionInfo)
{
if (ShowCrashConfirmation()) {
client->DumpAndCrash(ExceptionInfo);
}
QString crash_handler_exe = QDir(qApp->applicationDirPath()).filePath(QStringLiteral("olive-crashhandler"));
QProcess::startDetached(crash_handler_exe, {GenerateReportPath(), QString::number(QDateTime::currentSecsSinceEpoch())});
client->DumpAndCrash(ExceptionInfo);
return EXCEPTION_CONTINUE_SEARCH;
}
#elif defined(OS_LINUX)
bool LinuxExceptionHandler(int, siginfo_t*, ucontext_t*)
{
QString crash_handler_exe = QDir(qApp->applicationDirPath()).filePath(QStringLiteral("olive-crashhandler"));
QProcess::startDetached(crash_handler_exe, {GenerateReportPath(), QString::number(QDateTime::currentSecsSinceEpoch())});
// Returning false signals to Crashpad to proceed with its own exception handling
return false;
}
#endif
bool InitializeCrashpad()
{
QString exe_dir = QCoreApplication::applicationDirPath();
#ifdef OS_WIN
base::FilePath handler(QSTRING_TO_BASE_STRING(QDir(exe_dir).filePath(QStringLiteral("crashpad_handler.exe"))));
#else
// FIXME: On Linux, probably should put this in a subdir so that it doesn't conflict with
// anything else in /usr/bin
#ifdef Q_OS_WINDOWS
base::FilePath handler(TO_BASE_STRING_TYPE(QDir(exe_dir).filePath(QStringLiteral("crashpad_handler.exe"))));
#else
base::FilePath handler(TO_BASE_STRING_TYPE(QDir(exe_dir).filePath(QStringLiteral("crashpad_handler"))));
base::FilePath handler(QSTRING_TO_BASE_STRING(QDir(exe_dir).filePath(QStringLiteral("crashpad_handler"))));
#endif
base::FilePath reports_dir(TO_BASE_STRING_TYPE(QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath("reports")));
base::FilePath reports_dir = GenerateReportPathForCrashpad();
base::FilePath metrics_dir(TO_BASE_STRING_TYPE(QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath("metrics")));
std::string url = "https://olivevideoeditor.org/crashpad/report.php";
base::FilePath metrics_dir(QSTRING_TO_BASE_STRING(QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("metrics"))));
// Metadata that will be posted to the server with the crash report map
std::map<std::string, std::string> annotations;
@@ -105,19 +97,22 @@ bool InitializeCrashpad()
std::unique_ptr<crashpad::CrashReportDatabase> database = crashpad::CrashReportDatabase::Initialize(reports_dir);
if (database == NULL) return false;
// Enable automated crash uploads
// Disable automated crash uploads
crashpad::Settings *settings = database->GetSettings();
if (settings == NULL) return false;
settings->SetUploadsEnabled(true);
settings->SetUploadsEnabled(false);
// Start crash handler
client = new crashpad::CrashpadClient();
bool status = client->StartHandler(handler, reports_dir, metrics_dir,
url, annotations, arguments, true, true);
"https://olivevideoeditor.org/crashpad/report.php",
annotations, arguments, true, true);
// Override Crashpad exception filter with our own
#ifdef Q_OS_WINDOWS
#if defined(OS_WIN)
SetUnhandledExceptionFilter(Win32ExceptionHandler);
#elif defined(OS_LINUX)
crashpad::CrashpadClient::SetFirstChanceExceptionHandler(LinuxExceptionHandler);
#endif
return status;