diff --git a/.appveyor/build.bat b/.appveyor/build.bat
index e2c6b553f..51211c585 100644
--- a/.appveyor/build.bat
+++ b/.appveyor/build.bat
@@ -30,8 +30,17 @@ curl https://ffmpeg.zeranoe.com/builds/win64/shared/%FFMPEG_VER%-shared.zip > %F
7z x %FFMPEG_VER%-dev.zip
7z x %FFMPEG_VER%-shared.zip
-REM Add Qt and FFmpeg directory to path
-set PATH=%PATH%;C:\Qt\5.13.2\msvc2017_64\bin;%APPVEYOR_BUILD_FOLDER%\%FFMPEG_VER%-dev
+REM Acquire Google Crashpad
+git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
+set PATH=%PATH%;%APPVEYOR_BUILD_FOLDER%\depot_tools
+fetch crashpad
+cd crashpad
+gn gen out/Default
+ninja -C out/Default
+cd ..
+
+REM Add Qt, FFmpeg, and Crashpad to path
+set PATH=%PATH%;C:\Qt\5.13.2\msvc2017_64\bin;%APPVEYOR_BUILD_FOLDER%\%FFMPEG_VER%-dev;%APPVEYOR_BUILD_FOLDER%\crashpad;%APPVEYOR_BUILD_FOLDER%\crashpad\out\Default
REM Run cmake
cmake -G "Ninja" . -DCMAKE_TOOLCHAIN_FILE=c:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo
@@ -42,12 +51,18 @@ ninja.exe || exit /B 1
REM If this is a pull request, no further packaging/deploying needs to be done
if NOT "%APPVEYOR_PULL_REQUEST_NUMBER%" == "" goto end
+REM Create Crashpad symbol file and upload it
+wget https://github.com/google/breakpad/blob/master/src/tools/windows/binaries/dump_syms.exe?raw=true -O dump_syms.exe
+dump_syms app\olive-editor.pdb > olive-editor.sym
+curl -F symfile=@olive-editor.sym https://olivevideoeditor.org/crashpad/symbols.php
+
REM Start building package
mkdir olive-editor
cd olive-editor
copy ..\app\olive-editor.exe .
copy ..\app\olive-editor.pdb .
copy ..\app\crashhandler.exe .
+copy ..\crashpad\out\Default\crashpad_handler.exe .
windeployqt olive-editor.exe
copy ..\%FFMPEG_VER%-shared\bin\*.dll .
copy C:\Tools\vcpkg\installed\x64-windows\bin\OpenColorIO.dll .
@@ -85,9 +100,6 @@ REM Create portable
copy nul olive-editor\portable
7z a %PKGNAME%.zip olive-editor
-REM We're ready to upload, but we only upload *sometimes*
-REM set PATH=%PATH%;C:\msys64\usr\bin
-
REM If this was a tagged build, upload
if "%APPVEYOR_REPO_TAG%"=="true" GOTO upload
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 95a3ef62d..3c0f423c5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,6 +67,12 @@ find_package(FFMPEG 3.0 REQUIRED
swresample
)
+find_package(GoogleCrashpad)
+
+if (NOT GoogleCrashpad_FOUND)
+ message(" Automatic crash reporting will be disabled.")
+endif()
+
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
find_package(Git)
if(GIT_FOUND)
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 931702964..714a5e01d 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -79,9 +79,6 @@ if(APPLE)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9")
endif()
-# Set compiler definitions
-target_compile_definitions(${OLIVE_TARGET} PRIVATE ${OLIVE_DEFINITIONS})
-
# Set compiler options
if(MSVC)
target_compile_options(
@@ -171,6 +168,26 @@ elseif (APPLE)
)
endif()
+# Enable Crashpad if found
+if (GoogleCrashpad_FOUND)
+ set(OLIVE_DEFINITIONS ${OLIVE_DEFINITIONS} USE_CRASHPAD)
+
+ target_include_directories(
+ ${OLIVE_TARGET}
+ PRIVATE
+ ${CRASHPAD_INCLUDE_DIRS}
+ )
+
+ target_link_libraries(
+ ${OLIVE_TARGET}
+ PRIVATE
+ ${CRASHPAD_LIBRARIES}
+ )
+endif()
+
+# Set compiler definitions
+target_compile_definitions(${OLIVE_TARGET} PRIVATE ${OLIVE_DEFINITIONS})
+
set(OLIVE_TS_FILES
# FIXME: Empty variable
)
diff --git a/app/common/CMakeLists.txt b/app/common/CMakeLists.txt
index 295027196..0ee6714aa 100644
--- a/app/common/CMakeLists.txt
+++ b/app/common/CMakeLists.txt
@@ -23,6 +23,8 @@ set(OLIVE_SOURCES
common/clamp.h
common/crashhandler.h
common/crashhandler.cpp
+ common/crashpadinterface.cpp
+ common/crashpadinterface.h
common/debug.h
common/debug.cpp
common/define.h
diff --git a/app/common/crashpadinterface.cpp b/app/common/crashpadinterface.cpp
new file mode 100644
index 000000000..85cf37fad
--- /dev/null
+++ b/app/common/crashpadinterface.cpp
@@ -0,0 +1,82 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 Olive Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+***/
+
+#include "crashpadinterface.h"
+
+#ifdef USE_CRASHPAD
+
+#include
+#include
+#include
+
+#include "filefunctions.h"
+
+// 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
+
+bool InitializeCrashpad()
+{
+ QString exe_dir = QCoreApplication::applicationDirPath();
+
+ // FIXME: On Linux, probably should put this in a subdir so that it doesn't conflict with
+ // anything else in /usr/bin
+
+ base::FilePath handler(TO_BASE_STRING_TYPE(QDir(exe_dir).filePath(QStringLiteral("crashpad_handler.exe"))));
+
+ base::FilePath reports_dir(TO_BASE_STRING_TYPE(QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath("reports")));
+
+ base::FilePath metrics_dir(TO_BASE_STRING_TYPE(QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath("metrics")));
+
+ std::string url = "https://olivevideoeditor.org/crashpad/report.php";
+
+ // Metadata that will be posted to the server with the crash report map
+ std::map annotations;
+
+ // Disable crashpad rate limiting so that all crashes have dmp files
+ std::vector arguments;
+ arguments.push_back("--no-rate-limit");
+ arguments.push_back("--no-upload-gzip");
+
+ // Initialize Crashpad database
+ std::unique_ptr database = crashpad::CrashReportDatabase::Initialize(reports_dir);
+ if (database == NULL) return false;
+
+ // Enable automated crash uploads
+ crashpad::Settings *settings = database->GetSettings();
+ if (settings == NULL) return false;
+ settings->SetUploadsEnabled(true);
+
+ // Start crash handler
+ crashpad::CrashpadClient *client = new crashpad::CrashpadClient();
+ bool status = client->StartHandler(handler, reports_dir, metrics_dir,
+ url, annotations, arguments, true, true);
+ return status;
+}
+
+#endif // USE_CRASHPAD
diff --git a/app/common/crashpadinterface.h b/app/common/crashpadinterface.h
new file mode 100644
index 000000000..26bd17b65
--- /dev/null
+++ b/app/common/crashpadinterface.h
@@ -0,0 +1,34 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 Olive Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+***/
+
+#ifndef CRASHPAD_INTERFACE_H
+#define CRASHPAD_INTERFACE_H
+
+#ifdef USE_CRASHPAD
+
+#include
+#include
+#include
+
+bool InitializeCrashpad();
+
+#endif // USE_CRASHPAD
+
+#endif // CRASHPAD_INTERFACE_H
diff --git a/app/main.cpp b/app/main.cpp
index 0026395f0..d58b65ebf 100644
--- a/app/main.cpp
+++ b/app/main.cpp
@@ -32,17 +32,18 @@ extern "C" {
}
#include
+
#include
#include
#include "core.h"
-#include "common/crashhandler.h"
#include "common/debug.h"
-int main(int argc, char *argv[]) {
- signal(SIGSEGV, OLIVE_NAMESPACE::crash_handler);
- signal(SIGABRT, OLIVE_NAMESPACE::crash_handler);
+#ifdef USE_CRASHPAD
+#include "common/crashpadinterface.h"
+#endif // USE_CRASHPAD
+int main(int argc, char *argv[]) {
// Set OpenGL display profile (3.2 Core)
QSurfaceFormat format;
format.setVersion(3, 2);
@@ -86,5 +87,12 @@ int main(int argc, char *argv[]) {
avfilter_register_all();
#endif
+ // Enable Google Crashpad if compiled with it
+#ifdef USE_CRASHPAD
+ if (!InitializeCrashpad()) {
+ qWarning() << "Failed to initialize Crashpad handler";
+ }
+#endif // USE_CRASHPAD
+
return OLIVE_NAMESPACE::Core::instance()->execute(&a);
}
diff --git a/cmake/FindGoogleCrashpad.cmake b/cmake/FindGoogleCrashpad.cmake
new file mode 100644
index 000000000..4a5f2f2a9
--- /dev/null
+++ b/cmake/FindGoogleCrashpad.cmake
@@ -0,0 +1,82 @@
+# Olive - Non-Linear Video Editor
+# Copyright (C) 2019 Olive Team
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+include(FindPackageHandleStandardArgs)
+
+# Try to find include files
+find_path(CRASHPAD_CLIENT_INCLUDE_DIR
+ client/crashpad_client.h
+ HINTS
+ "${CRASHPAD_LOCATION}"
+ "$ENV{CRASHPAD_LOCATION}"
+ "${CRASHPAD_BASE_DIR}"
+)
+list(APPEND CRASHPAD_INCLUDE_DIRS ${CRASHPAD_CLIENT_INCLUDE_DIR})
+
+find_path(CRASHPAD_BASE_INCLUDE_DIR
+ base/files/file_path.h
+ HINTS
+ "${CRASHPAD_LOCATION}"
+ "$ENV{CRASHPAD_LOCATION}"
+ "${CRASHPAD_BASE_DIR}"
+ PATH_SUFFIXES
+ "third_party/mini_chromium/mini_chromium"
+)
+list(APPEND CRASHPAD_INCLUDE_DIRS ${CRASHPAD_BASE_INCLUDE_DIR})
+
+# Try to find build files
+if (WIN32)
+ find_path(CRASHPAD_LIBRARY_DIRS
+ obj/client/client.lib
+ HINTS
+ "${CRASHPAD_LOCATION}"
+ "$ENV{CRASHPAD_LOCATION}"
+ "${CRASHPAD_BASE_DIR}"
+ )
+elseif(UNIX)
+ # Assuming macOS works this way, don't actually know
+ find_path(CRASHPAD_LIBRARY_DIRS
+ obj/client/libclient.a
+ HINTS
+ "${CRASHPAD_LOCATION}"
+ "$ENV{CRASHPAD_LOCATION}"
+ "${CRASHPAD_BASE_DIR}"
+ )
+endif()
+
+# Find the libraries we need
+set (_crashpad_components
+ client/client
+ util/util
+ third_party/mini_chromium/mini_chromium/base/base)
+foreach (COMPONENT ${_crashpad_components})
+ string(REGEX MATCH "^(.*[\\\/])" SUBDIR ${COMPONENT})
+ string(REGEX MATCH "([^\/]+$)" SHORT_COMPONENT ${COMPONENT})
+ string(TOUPPER ${SHORT_COMPONENT} UPPERCOMPONENT)
+
+ find_library(CRASHPAD_${UPPERCOMPONENT}_LIB
+ ${SHORT_COMPONENT}
+ HINTS "${CRASHPAD_LIBRARY_DIRS}/obj/${SUBDIR}"
+ )
+
+ list(APPEND CRASHPAD_LIBRARIES ${CRASHPAD_${UPPERCOMPONENT}_LIB})
+endforeach()
+
+find_package_handle_standard_args(GoogleCrashpad
+ REQUIRED_VARS
+ CRASHPAD_LIBRARIES
+ CRASHPAD_INCLUDE_DIRS
+)