From ced5aad1d17efe7b9818f093330b350755cb3783 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 2 Nov 2017 11:14:35 -0700 Subject: [PATCH] backtrace for rc-63 --- cmake/externals/crashpad/CMakeLists.txt | 35 ++++++++ cmake/macros/AddCrashpad.cmake | 41 +++++++++ .../macros/PackageCrashpadForDeployment.cmake | 30 +++++++ cmake/modules/FindCrashpad.cmake | 41 +++++++++ interface/CMakeLists.txt | 2 + libraries/shared/CMakeLists.txt | 8 +- libraries/shared/src/shared/Crashpad.cpp | 87 +++++++++++++++++++ libraries/shared/src/shared/Crashpad.h | 17 ++++ 8 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 cmake/externals/crashpad/CMakeLists.txt create mode 100644 cmake/macros/AddCrashpad.cmake create mode 100644 cmake/macros/PackageCrashpadForDeployment.cmake create mode 100644 cmake/modules/FindCrashpad.cmake create mode 100644 libraries/shared/src/shared/Crashpad.cpp create mode 100644 libraries/shared/src/shared/Crashpad.h diff --git a/cmake/externals/crashpad/CMakeLists.txt b/cmake/externals/crashpad/CMakeLists.txt new file mode 100644 index 0000000000..c464dcbc1b --- /dev/null +++ b/cmake/externals/crashpad/CMakeLists.txt @@ -0,0 +1,35 @@ +include(ExternalProject) +set(EXTERNAL_NAME crashpad) + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + +if (WIN32) + ExternalProject_Add( + ${EXTERNAL_NAME} + URL https://backtrace.io/download/crashpad_062317.zip + URL_MD5 65817e564b3628492abfc1dbd2a1e98b + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD 1 + ) + + ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) + + set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE PATH "List of Crashpad include directories") + + set(LIB_EXT "lib") + + set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${SOURCE_DIR}/out/Release_x64/lib_MD/${LIB_PREFIX}crashpad_client.${LIB_EXT} CACHE FILEPATH "Path to Crashpad release library") + set(${EXTERNAL_NAME_UPPER}_BASE_LIBRARY_RELEASE ${SOURCE_DIR}/out/Release_x64/lib_MD/${LIB_PREFIX}base.${LIB_EXT} CACHE FILEPATH "Path to Crashpad base release library") + set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY_RELEASE ${SOURCE_DIR}/out/Release_x64/lib_MD/${LIB_PREFIX}crashpad_util.${LIB_EXT} CACHE FILEPATH "Path to Crashpad util release library") + + set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${SOURCE_DIR}/out/Debug_x64/lib_MD/${LIB_PREFIX}crashpad_client.${LIB_EXT} CACHE FILEPATH "Path to Crashpad debug library") + set(${EXTERNAL_NAME_UPPER}_BASE_LIBRARY_DEBUG ${SOURCE_DIR}/out/Debug_x64/lib_MD/${LIB_PREFIX}base.${LIB_EXT} CACHE FILEPATH "Path to Crashpad base debug library") + set(${EXTERNAL_NAME_UPPER}_UTIL_LIBRARY_DEBUG ${SOURCE_DIR}/out/Debug_x64/lib_MD/${LIB_PREFIX}crashpad_util.${LIB_EXT} CACHE FILEPATH "Path to Crashpad util debug library") + + set(CRASHPAD_HANDLER_EXE_PATH ${SOURCE_DIR}/out/Release_x64/crashpad_handler.exe CACHE FILEPATH "Path to the Crashpad handler executable") +endif () + +# Hide this external target (for ide users) +set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") diff --git a/cmake/macros/AddCrashpad.cmake b/cmake/macros/AddCrashpad.cmake new file mode 100644 index 0000000000..573e13c8a2 --- /dev/null +++ b/cmake/macros/AddCrashpad.cmake @@ -0,0 +1,41 @@ +# +# AddCrashpad.cmake +# cmake/macros +# +# Created by Clement Brisset on 01/19/18. +# Copyright 2018 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html +# + +macro(add_crashpad) + get_property(CRASHPAD_CHECKED GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE) + + set (USE_CRASHPAD TRUE) + if ("$ENV{CMAKE_BACKTRACE_URL}" STREQUAL "") + set (USE_CRASHPAD FALSE) + else() + set (CMAKE_BACKTRACE_URL $ENV{CMAKE_BACKTRACE_URL}) + endif() + + if ("$ENV{CMAKE_BACKTRACE_TOKEN}" STREQUAL "") + set (USE_CRASHPAD FALSE) + else() + set (CMAKE_BACKTRACE_TOKEN $ENV{CMAKE_BACKTRACE_TOKEN}) + endif() + + if (WIN32 AND USE_CRASHPAD AND NOT CRASHPAD_CHECKED) + set_property(GLOBAL PROPERTY HAS_CRASHPAD TRUE) + add_definitions(-DHAS_CRASHPAD) + add_definitions(-DCMAKE_BACKTRACE_URL=\"${CMAKE_BACKTRACE_URL}\") + add_definitions(-DCMAKE_BACKTRACE_TOKEN=\"${CMAKE_BACKTRACE_TOKEN}\") + + add_dependency_external_projects(crashpad) + find_package(crashpad REQUIRED) + target_include_directories(${TARGET_NAME} PRIVATE ${CRASHPAD_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${CRASHPAD_LIBRARY} ${CRASHPAD_BASE_LIBRARY} ${CRASHPAD_UTIL_LIBRARY}) + + set_property(GLOBAL PROPERTY CHECKED_FOR_CRASHPAD_ONCE TRUE) + endif () +endmacro() diff --git a/cmake/macros/PackageCrashpadForDeployment.cmake b/cmake/macros/PackageCrashpadForDeployment.cmake new file mode 100644 index 0000000000..adee7a79e6 --- /dev/null +++ b/cmake/macros/PackageCrashpadForDeployment.cmake @@ -0,0 +1,30 @@ +# +# PackageCrashpadForDeployment.cmake +# cmake/macros +# +# Copyright 2018 High Fidelity, Inc. +# Created by Clement Brisset on 01/19/18 +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +macro(PACKAGE_CRASHPAD_FOR_DEPLOYMENT) + get_property(HAS_CRASHPAD GLOBAL PROPERTY HAS_CRASHPAD) + + if (HAS_CRASHPAD) + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CRASHPAD_HANDLER_EXE_PATH} "$/" + ) + install( + PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/crashpad_handler.exe" + DESTINATION ${CLIENT_COMPONENT} + COMPONENT ${INTERFACE_INSTALL_DIR} + ) + + message(STATUS "CRASHPAD_HANDLER_EXE_PATH: ${CRASHPAD_HANDLER_EXE_PATH}") + message(STATUS "Target: $") + endif () +endmacro() diff --git a/cmake/modules/FindCrashpad.cmake b/cmake/modules/FindCrashpad.cmake new file mode 100644 index 0000000000..5095a0b0c9 --- /dev/null +++ b/cmake/modules/FindCrashpad.cmake @@ -0,0 +1,41 @@ +# +# FindCrashpad.cmake +# +# Try to find Crashpad libraries and include path. +# Once done this will define +# +# CRASHPAD_FOUND +# DRACO_INCLUDE_DIRS +# CRASHPAD_LIBRARY +# CRASHPAD_BASE_LIBRARY +# CRASHPAD_UTIL_LIBRARY +# +# Created on 01/19/2018 by Clement Brisset +# Copyright 2018 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") +hifi_library_search_hints("crashpad") + +find_path(CRASHPAD_INCLUDE_DIRS base/macros.h PATH_SUFFIXES include HINTS ${CRASHPAD_SEARCH_DIRS}) + +find_library(CRASHPAD_LIBRARY_RELEASE crashpad PATH_SUFFIXES "Release_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) +find_library(CRASHPAD_BASE_LIBRARY_RELEASE base PATH_SUFFIXES "Release_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) +find_library(CRASHPAD_UTIL_LIBRARY_RELEASE util PATH_SUFFIXES "Release_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) + +find_library(CRASHPAD_LIBRARY_DEBUG crashpad PATH_SUFFIXES "Debug_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) +find_library(CRASHPAD_BASE_LIBRARY_DEBUG base PATH_SUFFIXES "Debug_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) +find_library(CRASHPAD_UTIL_LIBRARY_DEBUG util PATH_SUFFIXES "Debug_x64/lib_MD" HINTS ${CRASHPAD_SEARCH_DIRS}) + +find_file(CRASHPAD_HANDLER_EXE_PATH NAME "crashpad_handler.exe" PATH_SUFFIXES "Release_x64" HINTS ${CRASHPAD_SEARCH_DIRS}) + +include(SelectLibraryConfigurations) +select_library_configurations(CRASHPAD) +select_library_configurations(CRASHPAD_BASE) +select_library_configurations(CRASHPAD_UTIL) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CRASHPAD DEFAULT_MSG CRASHPAD_INCLUDE_DIRS CRASHPAD_LIBRARY CRASHPAD_BASE_LIBRARY CRASHPAD_UTIL_LIBRARY) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 21225756b4..caa812e133 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -349,6 +349,8 @@ endif() add_bugsplat() +package_crashpad_for_deployment() + if (WIN32) set(EXTRA_DEPLOY_OPTIONS "--qmldir \"${PROJECT_SOURCE_DIR}/resources/qml\"") diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index f9b835df5c..379c15c999 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -5,7 +5,13 @@ setup_hifi_library(Gui Network Script Widgets) if (WIN32) target_link_libraries(${TARGET_NAME} Wbemuuid.lib) + + add_crashpad() +endif() + +if (ANDROID) + target_link_libraries(${TARGET_NAME} android) endif() target_zlib() -target_nsight() \ No newline at end of file +target_nsight() diff --git a/libraries/shared/src/shared/Crashpad.cpp b/libraries/shared/src/shared/Crashpad.cpp new file mode 100644 index 0000000000..a655ddec4b --- /dev/null +++ b/libraries/shared/src/shared/Crashpad.cpp @@ -0,0 +1,87 @@ +// +// Crashpad.cpp +// shared/src/shared +// +// Created by Clement Brisset on 01/19/18. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "Crashpad.h" + +#include + +#if HAS_CRASHPAD + +#include +#include + +#include + +#include +#include +#include + +using namespace crashpad; + +static const std::string BACKTRACE_URL { CMAKE_BACKTRACE_URL }; +static const std::string BACKTRACE_TOKEN { CMAKE_BACKTRACE_TOKEN }; + +extern QString qAppFileName(); + +bool startCrashHandler() { + if (BACKTRACE_URL.empty() || BACKTRACE_TOKEN.empty()) { + return false; + } + + CrashpadClient client; + std::map annotations; + std::vector arguments; + + annotations["token"] = BACKTRACE_TOKEN; + annotations["format"] = "minidump"; + annotations["service-name"] = BuildInfo::INTERFACE_NAME.toStdString(); + annotations["version"] = BuildInfo::VERSION.toStdString(); + + arguments.push_back("--no-rate-limit"); + + // Setup Crashpad DB directory + const auto crashpadDbName = "crashpad-db"; + const auto crashpadDbDir = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); + QDir(crashpadDbDir).mkpath(crashpadDbName); // Make sure the directory exists + const auto crashpadDbPath = crashpadDbDir.toStdString() + "/" + crashpadDbName; + + // Locate Crashpad handler + const std::string CRASHPAD_HANDLER_PATH = QFileInfo(qAppFileName()).absolutePath().toStdString() + "/crashpad_handler.exe"; + + // Setup different file paths + base::FilePath::StringType dbPath; + base::FilePath::StringType handlerPath; + dbPath.assign(crashpadDbPath.cbegin(), crashpadDbPath.cend()); + handlerPath.assign(CRASHPAD_HANDLER_PATH.cbegin(), CRASHPAD_HANDLER_PATH.cend()); + + base::FilePath db(dbPath); + base::FilePath handler(handlerPath); + + auto database = crashpad::CrashReportDatabase::Initialize(db); + if (database == nullptr || database->GetSettings() == nullptr) { + return false; + } + + // Enable automated uploads. + database->GetSettings()->SetUploadsEnabled(true); + + return client.StartHandler(handler, db, db, BACKTRACE_URL, annotations, arguments, true, true); +} + +#else + + +bool startCrashHandler() { + qDebug() << "No crash handler available."; + return false; +} + +#endif \ No newline at end of file diff --git a/libraries/shared/src/shared/Crashpad.h b/libraries/shared/src/shared/Crashpad.h new file mode 100644 index 0000000000..a40503a703 --- /dev/null +++ b/libraries/shared/src/shared/Crashpad.h @@ -0,0 +1,17 @@ +// +// Crashpad.h +// shared/src/shared +// +// Created by Clement Brisset on 01/19/18. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_Crashpad_h +#define hifi_Crashpad_h + +bool startCrashHandler(); + +#endif // hifi_Crashpad_h