From 748f45b7b84075bd4f5b4706fad0dadc9cf0f127 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 5 Apr 2021 13:33:21 +1000 Subject: [PATCH] merged new crashpad implementation --- .github/workflows/ci.yml | 9 +++- app/common/crashpadinterface.cpp | 44 ++------------------ app/dialog/crashhandler/crashhandler.cpp | 20 ++------- app/dialog/crashhandler/crashhandler.h | 6 +-- app/dialog/crashhandler/crashhandlermain.cpp | 20 ++++++++- cmake/FindGoogleCrashpad.cmake | 7 ++++ 6 files changed, 41 insertions(+), 65 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de7d1167d..863c12323 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -343,10 +343,17 @@ jobs: shell: bash run: | mv app/$BUNDLE_NAME . - $DEP_LOCATION/bin/macdeployqt $BUNDLE_NAME + $DEP_LOCATION/bin/macdeployqt $BUNDLE_NAME -executable=$BUNDLE_NAME/Contents/MacOS/olive-crashhandler $DOWNLOAD_TOOL https://github.com/arl/macdeployqtfix/raw/master/macdeployqtfix.py python2 macdeployqtfix.py $BUNDLE_NAME/Contents/MacOS/Olive $DEP_LOCATION + # Crashpad symbols + $DEP_LOCATION/bin/dump_syms $BUNDLE_NAME/Contents/MacOS/Olive > Olive.sym + SYM_HEADER=($(head -n 1 Olive.sym)) # Read first line of symbol file + SYM_DIR=$BUNDLE_NAME/Contents/Resources/symbols/Olive/${SYM_HEADER[3]} + mkdir -p "$SYM_DIR" + mv Olive.sym "$SYM_DIR" + # Manual fixes cp $DEP_LOCATION/lib/libopentimelineio.dylib $BUNDLE_NAME/Contents/Frameworks cp $DEP_LOCATION/lib/libopentime.dylib $BUNDLE_NAME/Contents/Frameworks diff --git a/app/common/crashpadinterface.cpp b/app/common/crashpadinterface.cpp index 300a12b86..e6a35ce3c 100644 --- a/app/common/crashpadinterface.cpp +++ b/app/common/crashpadinterface.cpp @@ -38,39 +38,10 @@ crashpad::CrashpadClient *client; -QString GenerateReportPath() -{ - return QDir(olive::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("reports")); -} - -base::FilePath GenerateReportPathForCrashpad() -{ - return base::FilePath(QSTRING_TO_BASE_STRING(GenerateReportPath())); -} - -#if defined(OS_WIN) -LONG WINAPI Win32ExceptionHandler(_EXCEPTION_POINTERS *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 report_path = QDir(olive::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("reports")); + QString handler_fn = olive::FileFunctions::GetFormattedExecutableForPlatform(QStringLiteral("crashpad_handler")); // Generate absolute path @@ -81,7 +52,7 @@ bool InitializeCrashpad() if (QFileInfo::exists(handler_abs_path)) { base::FilePath handler(QSTRING_TO_BASE_STRING(handler_abs_path)); - base::FilePath reports_dir = GenerateReportPathForCrashpad(); + base::FilePath reports_dir(QSTRING_TO_BASE_STRING(report_path)); base::FilePath metrics_dir(QSTRING_TO_BASE_STRING(QDir(olive::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("metrics")))); @@ -109,15 +80,8 @@ bool InitializeCrashpad() annotations, arguments, true, true); } - // Override Crashpad exception filter with our own - if (status) { -#if defined(OS_WIN) - SetUnhandledExceptionFilter(Win32ExceptionHandler); -#elif defined(OS_LINUX) - crashpad::CrashpadClient::SetFirstChanceExceptionHandler(LinuxExceptionHandler); -#endif - } else { + if (!status) { qWarning() << "Failed to start Crashpad, automatic crash reporting will be disabled"; } diff --git a/app/dialog/crashhandler/crashhandler.cpp b/app/dialog/crashhandler/crashhandler.cpp index 54c174004..3f31748de 100644 --- a/app/dialog/crashhandler/crashhandler.cpp +++ b/app/dialog/crashhandler/crashhandler.cpp @@ -41,13 +41,12 @@ namespace olive { -CrashHandlerDialog::CrashHandlerDialog(const char *report_dir, const char* crash_time) +CrashHandlerDialog::CrashHandlerDialog(const QString& report_path) { setWindowTitle(tr("Olive")); setWindowFlags(Qt::WindowStaysOnTopHint); - crash_time_ = QString(crash_time).toULongLong(); - report_dir_ = report_dir; + report_filename_ = report_path; waiting_for_upload_ = false; QVBoxLayout* layout = new QVBoxLayout(this); @@ -97,7 +96,7 @@ CrashHandlerDialog::CrashHandlerDialog(const char *report_dir, const char* crash crash_report_->setText(tr("Waiting for crash report to be generated...")); - AttemptToFindReport(); + GenerateReport(); } void CrashHandlerDialog::SetGUIObjectsEnabled(bool e) @@ -158,19 +157,6 @@ void CrashHandlerDialog::ReplyFinished(QNetworkReply* reply) void CrashHandlerDialog::AttemptToFindReport() { - // Retrieve reports from Crashpad database - std::unique_ptr database = crashpad::CrashReportDatabase::Initialize(base::FilePath(QSTRING_TO_BASE_STRING(QString(report_dir_)))); - std::vector reports; - database->GetCompletedReports(&reports); - - // Find report that was made after the crash time - foreach (const crashpad::CrashReportDatabase::Report& report, reports) { - if (report.creation_time >= crash_time_) { - report_filename_ = BASE_STRING_TO_QSTRING(report.file_path.value()); - break; - } - } - // If we found it, use it, otherwise wait a second and try again if (report_filename_.isEmpty()) { // Couldn't find report, try again in one second diff --git a/app/dialog/crashhandler/crashhandler.h b/app/dialog/crashhandler/crashhandler.h index 058bb93fe..2ee5049ab 100644 --- a/app/dialog/crashhandler/crashhandler.h +++ b/app/dialog/crashhandler/crashhandler.h @@ -36,7 +36,7 @@ class CrashHandlerDialog : public QDialog { Q_OBJECT public: - CrashHandlerDialog(const char* report_dir, const char* crash_time); + CrashHandlerDialog(const QString& report_path); private: void SetGUIObjectsEnabled(bool e); @@ -55,10 +55,6 @@ private: QString report_filename_; - time_t crash_time_; - - QString report_dir_; - QByteArray report_data_; bool waiting_for_upload_; diff --git a/app/dialog/crashhandler/crashhandlermain.cpp b/app/dialog/crashhandler/crashhandlermain.cpp index 7142fc244..df8c375b7 100644 --- a/app/dialog/crashhandler/crashhandlermain.cpp +++ b/app/dialog/crashhandler/crashhandlermain.cpp @@ -24,13 +24,29 @@ int main(int argc, char *argv[]) { - if (argc < 3) { + QString report; + +#ifdef Q_OS_WINDOWS + int num_args; + LPWSTR *args = CommandLineToArgvW(GetCommandLineW(), &num_args); + if (num_args < 2) { + LocalFree(args); return 1; } + report = QString::fromWCharArray(args[1]); + LocalFree(args); +#else + if (argc < 2) { + return 1; + } + + report = argv[1]; +#endif + QApplication a(argc, argv); - olive::CrashHandlerDialog chd(argv[1], argv[2]); + olive::CrashHandlerDialog chd(report); chd.open(); return a.exec(); diff --git a/cmake/FindGoogleCrashpad.cmake b/cmake/FindGoogleCrashpad.cmake index 068e8a959..d48732156 100644 --- a/cmake/FindGoogleCrashpad.cmake +++ b/cmake/FindGoogleCrashpad.cmake @@ -108,6 +108,7 @@ foreach (COMPONENT ${_crashpad_components}) ${SHORT_COMPONENT} HINTS "${CRASHPAD_LIBRARY_DIRS}/obj/${COMPONENT}" + NO_DEFAULT_PATH ) list(APPEND CRASHPAD_LIBRARIES ${CRASHPAD_${UPPER_COMPONENT}_LIB}) @@ -177,3 +178,9 @@ if (UNIX AND NOT APPLE) Threads::Threads # Link against libpthread.so (-lpthread) ) endif() + +if (WIN32) + list(APPEND CRASHPAD_LIBRARIES + shlwapi.lib # Only necessary for our fork of Crashpad + ) +endif()