From e56f83de9ec168748588f6a73c9dbecaebe72fe7 Mon Sep 17 00:00:00 2001 From: Ryp Date: Tue, 24 Oct 2023 20:03:56 +0300 Subject: [PATCH] WIP external: add google breakpad/crashpad integration NPT-91 --- .github/workflows/build.yml | 5 +- .gitmodules | 9 +++ CMakeLists.txt | 12 ++- cmake/external/breakpad.cmake | 22 ++++++ cmake/external/crashpad.cmake | 109 ++++++++++++++++++++++++++++ external/google/breakpad/.gclient | 8 ++ external/google/breakpad/.gitignore | 4 + external/google/breakpad/src | 1 + external/google/crashpad/.gclient | 7 ++ external/google/crashpad/.gitignore | 7 ++ external/google/crashpad/crashpad | 1 + external/google/depot_tools | 1 + external/google/metrics.cfg | 1 + src/BreakpadHandler.cpp | 85 ++++++++++++++++++++++ src/BreakpadHandler.h | 24 ++++++ src/CMakeLists.txt | 21 +++++- src/CrashpadHandler.cpp | 61 ++++++++++++++++ src/CrashpadHandler.h | 25 +++++++ src/core/CMakeLists.txt | 2 + src/core/Crash.cpp | 17 +++++ src/core/Crash.h | 15 ++++ src/main.cpp | 39 +++++++++- 22 files changed, 469 insertions(+), 7 deletions(-) create mode 100644 cmake/external/breakpad.cmake create mode 100644 cmake/external/crashpad.cmake create mode 100644 external/google/breakpad/.gclient create mode 100644 external/google/breakpad/.gitignore create mode 160000 external/google/breakpad/src create mode 100644 external/google/crashpad/.gclient create mode 100644 external/google/crashpad/.gitignore create mode 160000 external/google/crashpad/crashpad create mode 160000 external/google/depot_tools create mode 100644 external/google/metrics.cfg create mode 100644 src/BreakpadHandler.cpp create mode 100644 src/BreakpadHandler.h create mode 100644 src/CrashpadHandler.cpp create mode 100644 src/CrashpadHandler.h create mode 100644 src/core/Crash.cpp create mode 100644 src/core/Crash.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b4985599..6d5534ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,7 +49,7 @@ jobs: - name: Install dependencies run: | sudo apt-get update -qq # Always do this step to prevent package urls to get outdated - sudo apt-get install -y build-essential cmake gcc libunwind-dev libx11-xcb-dev libxcb-xkb-dev libasound2-dev + sudo apt-get install -y build-essential cmake gcc ninja-build libcurl libunwind-dev libx11-xcb-dev libxcb-xkb-dev libasound2-dev - name: Prepare Vulkan SDK uses: humbletim/setup-vulkan-sdk@v1.2.0 @@ -123,6 +123,9 @@ jobs: vulkan-components: ${{ env.vulkan_sdk_modules }} vulkan-use-cache: true + - name: Install Ninja + uses: seanmiddleditch/gha-setup-ninja@master + - name: Configure CMake run: | cmake .\ -Bbuild ` diff --git a/.gitmodules b/.gitmodules index 09650541..5ca93fb3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -39,3 +39,12 @@ [submodule "external/bullet3"] path = external/bullet3 url = https://github.com/Ryp/bullet3 +[submodule "external/google/depot_tools"] + path = external/google/depot_tools + url = https://chromium.googlesource.com/chromium/tools/depot_tools.git +[submodule "external/google/breakpad/src"] + path = external/google/breakpad/src + url = https://chromium.googlesource.com/breakpad/breakpad.git +[submodule "external/google/crashpad/crashpad"] + path = external/google/crashpad/crashpad + url = https://chromium.googlesource.com/crashpad/crashpad.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 760dee63..affc2e84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,13 @@ option(REAPER_BUILD_SHARED_LIBS "Build shared libraries" ${BUILD_ # Enable runtime profiling with Tracy. # Tracy has its own profiler app that you have to compile from source. -option(REAPER_USE_TRACY "Use tracy" ON) +option(REAPER_USE_TRACY "Use Tracy" ON) + +# Enable crash reporting with google breakpad +option(REAPER_USE_GOOGLE_BREAKPAD "Use Google Breakpad" OFF) + +# Enable crash reporting with google crashpad +option(REAPER_USE_GOOGLE_CRASHPAD "Use Google Crashpad" ON) # See .clang-tidy for the list of useful checks. option(REAPER_RUN_CLANG_TIDY "Run clang-tidy when compiling" OFF) @@ -80,6 +86,10 @@ option(REAPER_HLSL_USE_DXC "Build HLSL shaders with DXC" OFF) # Enable physics simulation with bullet. option(REAPER_USE_BULLET_PHYSICS "Enable game physics" ON) +if(REAPER_USE_GOOGLE_BREAKPAD AND REAPER_USE_GOOGLE_CRASHPAD) + message(FATAL_ERROR "Google breakpad and crashpad can't be both enabled at the same time!") +endif() + # Override binary output paths set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Reaper_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${Reaper_BINARY_DIR}) diff --git a/cmake/external/breakpad.cmake b/cmake/external/breakpad.cmake new file mode 100644 index 00000000..47112813 --- /dev/null +++ b/cmake/external/breakpad.cmake @@ -0,0 +1,22 @@ +#/////////////////////////////////////////////////////////////////////////////// +#// Reaper +#// +#// Copyright (c) 2015-2023 Thibault Schueller +#// This file is distributed under the MIT License +#/////////////////////////////////////////////////////////////////////////////// + +set(GOOGLE_BREAKPAD_PATH ${CMAKE_SOURCE_DIR}/external/google/breakpad/src) + +add_library(google_breakpad INTERFACE) + +target_include_directories(google_breakpad SYSTEM INTERFACE ${GOOGLE_BREAKPAD_PATH}/src) + +if(WIN32) + target_include_directories(google_breakpad SYSTEM INTERFACE ${GOOGLE_BREAKPAD_PATH}/src/client/windows) + target_link_directories(google_breakpad INTERFACE ${GOOGLE_BREAKPAD_PATH}/src/client/windows) +elseif(UNIX) + target_include_directories(google_breakpad SYSTEM INTERFACE ${GOOGLE_BREAKPAD_PATH}/src/client/linux) + target_link_directories(google_breakpad INTERFACE ${GOOGLE_BREAKPAD_PATH}/src/client/linux) +endif() + +target_link_libraries(google_breakpad INTERFACE breakpad_client) diff --git a/cmake/external/crashpad.cmake b/cmake/external/crashpad.cmake new file mode 100644 index 00000000..c005392c --- /dev/null +++ b/cmake/external/crashpad.cmake @@ -0,0 +1,109 @@ +#/////////////////////////////////////////////////////////////////////////////// +#// Reaper +#// +#// Copyright (c) 2015-2023 Thibault Schueller +#// This file is distributed under the MIT License +#/////////////////////////////////////////////////////////////////////////////// + +set(GOOGLE_PATH ${CMAKE_SOURCE_DIR}/external/google) + +set(GOOGLE_BREAKPAD_PATH ${GOOGLE_PATH}/breakpad/src) +set(GOOGLE_CRASHPAD_PATH ${GOOGLE_PATH}/crashpad/crashpad) +set(GOOGLE_DEPOT_TOOLS_PATH ${GOOGLE_PATH}/depot_tools) + +# depot_tools used to contain the ninja binary but doesn't anymore, so we need +# to make sure it's in the PATH instead of sourcing it from google's repo. +find_program(EXE_NINJA ninja REQUIRED) + +list(APPEND CMAKE_PROGRAM_PATH ${GOOGLE_DEPOT_TOOLS_PATH}) +find_program(GOOGLE_DEPOT_TOOLS_GCLIENT gclient REQUIRED) +find_program(GOOGLE_DEPOT_TOOLS_GN gn REQUIRED) + +# gclient sync will try to update the local clone of depot_tools +# creating this file will inhibit that behavior +file(TOUCH ${GOOGLE_DEPOT_TOOLS_PATH}/.disable_auto_update) + +# TODO Comment +file(COPY ${GOOGLE_PATH}/metrics.cfg DESTINATION ${GOOGLE_DEPOT_TOOLS_PATH}) + +# NOTE: Partial dependency checking. +# It's not enough to mark the gclient file as the only byproduct, +# as there's many more files produced by this command. +# For the sake simplicity, I'm not going to bother making that step bulletproof. +set(GOOGLE_CRASHPAD_GCLIENT_ENTRIES_FILE ${GOOGLE_PATH}/crashpad/.gclient_entries) + +add_custom_command(OUTPUT ${GOOGLE_CRASHPAD_GCLIENT_ENTRIES_FILE} + COMMENT "Configure google crashpad repo" + WORKING_DIRECTORY ${GOOGLE_PATH}/crashpad + COMMAND ${GOOGLE_DEPOT_TOOLS_GCLIENT} sync --nohooks) + +set(GOOGLE_CRASHPAD_BINARY_DIR ${CMAKE_BINARY_DIR}/external/crashpad) + +#Lists of the expected output libraries +if(WIN32) + list(APPEND GOOGLE_CRASHPAD_CLIENT_LIBRARIES + ${GOOGLE_CRASHPAD_BINARY_DIR}/obj/client/client.lib + ${GOOGLE_CRASHPAD_BINARY_DIR}/obj/client/common.lib + ${GOOGLE_CRASHPAD_BINARY_DIR}/obj/util/util.lib + ${GOOGLE_CRASHPAD_BINARY_DIR}/obj/third_party/mini_chromium/mini_chromium/base/base.lib) +elseif(UNIX) + list(APPEND GOOGLE_CRASHPAD_CLIENT_LIBRARIES + ${GOOGLE_CRASHPAD_BINARY_DIR}/obj/client/libclient.a + ${GOOGLE_CRASHPAD_BINARY_DIR}/obj/client/libcommon.a + ${GOOGLE_CRASHPAD_BINARY_DIR}/obj/util/libutil.a + ${GOOGLE_CRASHPAD_BINARY_DIR}/obj/third_party/mini_chromium/mini_chromium/base/libbase.a) +endif() + +set(GN_IS_DEBUG) +set(GN_LINK_FLAG) + +# FIXME multi-config generators +if(CMAKE_BUILD_TYPE STREQUAL Debug) + set(GN_IS_DEBUG true) +else() + set(GN_IS_DEBUG false) +endif() + +# FIXME multi-config generators +if(MSVC) + if(CMAKE_BUILD_TYPE STREQUAL Debug) + set(GN_LINK_FLAG /MDd) + else() + set(GN_LINK_FLAG /MD) + endif() +endif() + +set(GOOGLE_CRASHPAD_NINJA_FILE ${GOOGLE_CRASHPAD_BINARY_DIR}/build.ninja) + +# NOTE: Partial dependency checking. +# It's not enough to mark the ninja file as the only byproduct, +# as there's many more files needed by ninja after a configure step to produce a correct build. +# For the sake simplicity, I'm not going to bother making that step bulletproof. +add_custom_command(OUTPUT ${GOOGLE_CRASHPAD_NINJA_FILE} + COMMENT "Configure google crashpad handler" + DEPENDS ${GOOGLE_CRASHPAD_GCLIENT_ENTRIES_FILE} + WORKING_DIRECTORY ${GOOGLE_CRASHPAD_PATH} + COMMAND ${CMAKE_COMMAND} -E make_directory ${GOOGLE_CRASHPAD_BINARY_DIR} + COMMAND ${GOOGLE_DEPOT_TOOLS_GN} gen ${GOOGLE_CRASHPAD_BINARY_DIR} "--args=is_debug=${GN_IS_DEBUG} extra_cflags=\"${GN_LINK_FLAG}\"" + VERBATIM) + +add_custom_command(OUTPUT ${GOOGLE_CRASHPAD_CLIENT_LIBRARIES} + COMMENT "Compile google crashpad handler" + DEPENDS ${GOOGLE_CRASHPAD_NINJA_FILE} + COMMAND ${EXE_NINJA} -C ${GOOGLE_CRASHPAD_BINARY_DIR} crashpad_handler + VERBATIM) + +add_custom_target(crashpad_handler_compile DEPENDS ${GOOGLE_CRASHPAD_CLIENT_LIBRARIES}) + +# Meta target +add_library(google_crashpad_client INTERFACE) + +add_dependencies(google_crashpad_client crashpad_handler_compile) + +target_link_libraries(google_crashpad_client INTERFACE ${GOOGLE_CRASHPAD_CLIENT_LIBRARIES}) + +target_include_directories(google_crashpad_client SYSTEM INTERFACE + ${GOOGLE_CRASHPAD_PATH} + ${GOOGLE_CRASHPAD_PATH}/third_party/mini_chromium/mini_chromium + ${GOOGLE_CRASHPAD_BINARY_DIR}/gen +) diff --git a/external/google/breakpad/.gclient b/external/google/breakpad/.gclient new file mode 100644 index 00000000..41550519 --- /dev/null +++ b/external/google/breakpad/.gclient @@ -0,0 +1,8 @@ +solutions = [ + { + "name": "src", + "url": "https://chromium.googlesource.com/breakpad/breakpad.git", + "managed": False, + "custom_deps": {}, + }, +] diff --git a/external/google/breakpad/.gitignore b/external/google/breakpad/.gitignore new file mode 100644 index 00000000..075ff904 --- /dev/null +++ b/external/google/breakpad/.gitignore @@ -0,0 +1,4 @@ +!.gitignore + +.gclient_entries +.gclient_previous_sync_commits diff --git a/external/google/breakpad/src b/external/google/breakpad/src new file mode 160000 index 00000000..f49c2f1a --- /dev/null +++ b/external/google/breakpad/src @@ -0,0 +1 @@ +Subproject commit f49c2f1a2023da0cb055874fba050563dfea57db diff --git a/external/google/crashpad/.gclient b/external/google/crashpad/.gclient new file mode 100644 index 00000000..3ceff584 --- /dev/null +++ b/external/google/crashpad/.gclient @@ -0,0 +1,7 @@ +solutions = [ + { + "name": "crashpad", + "url": "https://chromium.googlesource.com/crashpad/crashpad.git", + "managed": False, + }, +] diff --git a/external/google/crashpad/.gitignore b/external/google/crashpad/.gitignore new file mode 100644 index 00000000..6595d768 --- /dev/null +++ b/external/google/crashpad/.gitignore @@ -0,0 +1,7 @@ +!.gitignore + +.cipd +.gclient_entries +.gclient_previous_sync_commits + +buildtools \ No newline at end of file diff --git a/external/google/crashpad/crashpad b/external/google/crashpad/crashpad new file mode 160000 index 00000000..4a93d7f4 --- /dev/null +++ b/external/google/crashpad/crashpad @@ -0,0 +1 @@ +Subproject commit 4a93d7f4c407fee2168ea23195d0e30fbfc1f90c diff --git a/external/google/depot_tools b/external/google/depot_tools new file mode 160000 index 00000000..c7628f78 --- /dev/null +++ b/external/google/depot_tools @@ -0,0 +1 @@ +Subproject commit c7628f780970136892e71d9de0dee072a1982dc9 diff --git a/external/google/metrics.cfg b/external/google/metrics.cfg new file mode 100644 index 00000000..dcfedc74 --- /dev/null +++ b/external/google/metrics.cfg @@ -0,0 +1 @@ +{"is-googler": false, "countdown": 10, "opt-in": null, "version": 2} \ No newline at end of file diff --git a/src/BreakpadHandler.cpp b/src/BreakpadHandler.cpp new file mode 100644 index 00000000..66e0f44d --- /dev/null +++ b/src/BreakpadHandler.cpp @@ -0,0 +1,85 @@ +//////////////////////////////////////////////////////////////////////////////// +/// Reaper +/// +/// Copyright (c) 2015-2023 Thibault Schueller +/// This file is distributed under the MIT License +//////////////////////////////////////////////////////////////////////////////// + +#include "BreakpadHandler.h" + +#include +#include + +#include "handler/exception_handler.h" + +#if defined(REAPER_PLATFORM_LINUX) +static bool dump_callback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) + +{ + static_cast(context); + static_cast(descriptor); + + return succeeded; +} +#elif defined(REAPER_PLATFORM_WINDOWS) +# include +constexpr size_t kMaximumLineLength = 256; +constexpr wchar_t kPipeName[] = L"\\\\.\\pipe\\BreakpadCrashServices\\TestServer"; +static size_t kCustomInfoCount = 2; + +static google_breakpad::CustomInfoEntry kCustomInfoEntries[] = { + {L"prod", L"CrashTestApp"}, + {L"ver", L"1.0"}, +}; + +bool ShowDumpResults(const wchar_t* dump_path, + const wchar_t* minidump_id, + void* context, + EXCEPTION_POINTERS* exinfo, + MDRawAssertionInfo* assertion, + bool succeeded) +{ + return succeeded; +} +#endif + +namespace Reaper +{ +BreakpadContext create_breakpad_context() +{ +#if defined(REAPER_PLATFORM_LINUX) + const char* dump_path = "/tmp"; +#elif defined(REAPER_PLATFORM_WINDOWS) + const wchar_t* dump_path = L"C:\\dumps\\"; +#endif + +#if defined(REAPER_PLATFORM_LINUX) + google_breakpad::MinidumpDescriptor descriptor(dump_path); + + auto* handler = new google_breakpad::ExceptionHandler(descriptor, nullptr, dump_callback, nullptr, true, 1); +#elif defined(REAPER_PLATFORM_WINDOWS) + google_breakpad::CustomClientInfo custom_info = {kCustomInfoEntries, kCustomInfoCount}; + + auto* handler = new google_breakpad::ExceptionHandler(dump_path, + nullptr, + ShowDumpResults, + nullptr, + google_breakpad::ExceptionHandler::HANDLER_ALL, + MiniDumpNormal, + kPipeName, + &custom_info); +#endif + + return BreakpadContext{.handler = handler}; +} + +void destroy_breakpad_context(const BreakpadContext& breakpad_context) +{ + Assert(breakpad_context.handler); + + if (breakpad_context.handler) + { + delete breakpad_context.handler; + } +} +} // namespace Reaper diff --git a/src/BreakpadHandler.h b/src/BreakpadHandler.h new file mode 100644 index 00000000..039665fd --- /dev/null +++ b/src/BreakpadHandler.h @@ -0,0 +1,24 @@ +//////////////////////////////////////////////////////////////////////////////// +/// Reaper +/// +/// Copyright (c) 2015-2023 Thibault Schueller +/// This file is distributed under the MIT License +//////////////////////////////////////////////////////////////////////////////// + +#pragma once + +namespace google_breakpad +{ +class ExceptionHandler; +} + +namespace Reaper +{ +struct BreakpadContext +{ + google_breakpad::ExceptionHandler* handler; +}; + +BreakpadContext create_breakpad_context(); +void destroy_breakpad_context(const BreakpadContext& breakpad_context); +} // namespace Reaper diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 11de568f..988ba084 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,7 +27,6 @@ add_executable(${REAPER_BIN}) target_sources(${REAPER_BIN} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Camera.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Camera.h ${CMAKE_CURRENT_SOURCE_DIR}/GameLoop.cpp @@ -50,6 +49,26 @@ target_link_libraries(${REAPER_BIN} PRIVATE cgltf ) +if(REAPER_USE_GOOGLE_BREAKPAD) + target_sources(${REAPER_BIN} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/BreakpadHandler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/BreakpadHandler.h) + + include(external/breakpad) + target_compile_definitions(${REAPER_BIN} PUBLIC REAPER_USE_GOOGLE_BREAKPAD) + target_link_libraries(${REAPER_BIN} PRIVATE google_breakpad) +endif() + +if(REAPER_USE_GOOGLE_CRASHPAD) + target_sources(${REAPER_BIN} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CrashpadHandler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/CrashpadHandler.h) + + include(external/crashpad) + target_compile_definitions(${REAPER_BIN} PUBLIC REAPER_USE_GOOGLE_CRASHPAD) + target_link_libraries(${REAPER_BIN} PRIVATE google_crashpad_client) +endif() + # Configure main VS projet set_target_properties(${REAPER_BIN} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${REAPER_BIN}) diff --git a/src/CrashpadHandler.cpp b/src/CrashpadHandler.cpp new file mode 100644 index 00000000..aabd02f4 --- /dev/null +++ b/src/CrashpadHandler.cpp @@ -0,0 +1,61 @@ +//////////////////////////////////////////////////////////////////////////////// +/// Reaper +/// +/// Copyright (c) 2015-2023 Thibault Schueller +/// This file is distributed under the MIT License +//////////////////////////////////////////////////////////////////////////////// + +#include "CrashpadHandler.h" + +#include "client/crash_report_database.h" +#include "client/crashpad_client.h" +#include "client/settings.h" +#include "client/simulate_crash.h" + +#include +#include + +// FIXME CRASHPAD_SIMULATE_CRASH(); + +namespace Reaper +{ +CrashpadContext create_crashpad_context() +{ + // FIXME +#if defined(REAPER_PLATFORM_LINUX) + auto database_dir = base::FilePath("/tmp"); + auto handler_path = base::FilePath("build/external/crashpad/crashpad_handler"); +#elif defined(REAPER_PLATFORM_WINDOWS) + auto database_dir = base::FilePath(L"C:\\tmp"); + auto handler_path = base::FilePath(L"crashpad_handler.exe"); +#endif + + auto metrics_dir = database_dir; + const char* upload_url = "https://crash.neptune.com/upload?client_key=deadc0ffee"; + + auto database = crashpad::CrashReportDatabase::Initialize(database_dir); + + if (database == nullptr) + { + return CrashpadContext{.client = nullptr, .is_started = false}; + } + + auto* client = new crashpad::CrashpadClient(); + bool status = client->StartHandler(handler_path, database_dir, metrics_dir, upload_url, {}, {}, true, false, {}); + + return CrashpadContext{ + .client = client, + .is_started = status, + }; +} + +void destroy_crashpad_context(const CrashpadContext& crashpad_context) +{ + Assert(crashpad_context.is_started); + + if (crashpad_context.is_started) + { + delete crashpad_context.client; + } +} +} // namespace Reaper diff --git a/src/CrashpadHandler.h b/src/CrashpadHandler.h new file mode 100644 index 00000000..83caa97b --- /dev/null +++ b/src/CrashpadHandler.h @@ -0,0 +1,25 @@ +//////////////////////////////////////////////////////////////////////////////// +/// Reaper +/// +/// Copyright (c) 2015-2023 Thibault Schueller +/// This file is distributed under the MIT License +//////////////////////////////////////////////////////////////////////////////// + +#pragma once + +namespace crashpad +{ +class CrashpadClient; +} + +namespace Reaper +{ +struct CrashpadContext +{ + crashpad::CrashpadClient* client; + bool is_started; +}; + +CrashpadContext create_crashpad_context(); +void destroy_crashpad_context(const CrashpadContext& crashpad_context); +} // namespace Reaper diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 47a8b132..a1917689 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -14,6 +14,8 @@ target_sources(${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Assert.h ${CMAKE_CURRENT_SOURCE_DIR}/BitTricks.h ${CMAKE_CURRENT_SOURCE_DIR}/Cast.h + ${CMAKE_CURRENT_SOURCE_DIR}/Crash.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Crash.h ${CMAKE_CURRENT_SOURCE_DIR}/Compiler.h ${CMAKE_CURRENT_SOURCE_DIR}/CoreExport.h ${CMAKE_CURRENT_SOURCE_DIR}/Debugger.cpp diff --git a/src/core/Crash.cpp b/src/core/Crash.cpp new file mode 100644 index 00000000..da9703a2 --- /dev/null +++ b/src/core/Crash.cpp @@ -0,0 +1,17 @@ +//////////////////////////////////////////////////////////////////////////////// +/// Reaper +/// +/// Copyright (c) 2015-2023 Thibault Schueller +/// This file is distributed under the MIT License +//////////////////////////////////////////////////////////////////////////////// + +#include "Crash.h" + +namespace Reaper +{ +void trigger_crash() +{ + volatile int* a = (int*)(0); + *a = 1; +} +} // namespace Reaper diff --git a/src/core/Crash.h b/src/core/Crash.h new file mode 100644 index 00000000..3109a1f6 --- /dev/null +++ b/src/core/Crash.h @@ -0,0 +1,15 @@ +//////////////////////////////////////////////////////////////////////////////// +/// Reaper +/// +/// Copyright (c) 2015-2023 Thibault Schueller +/// This file is distributed under the MIT License +//////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "CoreExport.h" + +namespace Reaper +{ +REAPER_CORE_API void trigger_crash(); +} // namespace Reaper diff --git a/src/main.cpp b/src/main.cpp index 586f465a..033b3946 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,16 @@ #include "GameLoop.h" +#include + +#if defined(REAPER_USE_GOOGLE_CRASHPAD) +# include "CrashpadHandler.h" +#endif + +#if defined(REAPER_USE_GOOGLE_BREAKPAD) +# include "BreakpadHandler.h" +#endif + namespace Reaper { namespace @@ -51,13 +61,34 @@ namespace int main(int /*ac*/, char** /*av*/) { - Reaper::ReaperRoot root = {}; + using namespace Reaper; + +#if defined(REAPER_USE_GOOGLE_BREAKPAD) + BreakpadContext breakpad_context = create_breakpad_context(); +#endif + +#if defined(REAPER_USE_GOOGLE_CRASHPAD) + CrashpadContext crashpad_context = create_crashpad_context(); + Assert(crashpad_context.is_started); +#endif - Reaper::start_engine(root); + { + ReaperRoot root = {}; + + start_engine(root); + + execute_game_loop(root); + + stop_engine(root); + } - Reaper::execute_game_loop(root); +#if defined(REAPER_USE_GOOGLE_CRASHPAD) + destroy_crashpad_context(crashpad_context); +#endif - Reaper::stop_engine(root); +#if defined(REAPER_USE_GOOGLE_BREAKPAD) + destroy_breakpad_context(breakpad_context); +#endif return 0; }