diff --git a/Modules/BreakpadCrashReporting/CMakeLists.txt b/Modules/BreakpadCrashReporting/CMakeLists.txt index 211e02894a..b4787737f5 100644 --- a/Modules/BreakpadCrashReporting/CMakeLists.txt +++ b/Modules/BreakpadCrashReporting/CMakeLists.txt @@ -1,63 +1,64 @@ # TODOs # - nicer separation of Linux/Window/.. code # - test should check existence of dump file # - find nice script to use linux symbol writer tool dump_.. on all relevant libraries # - update documentation +# - check buildtype (O2/-g/..) in cmake # - use the same library structure in "our" cmake script as google uses in their build # - otherwise we cannot switch between custom-built versions of breakpad and our superbuild version if(MITK_USE_BREAKPAD) message(STATUS "Get directory hint for Breakpad:") message(STATUS ${Breakpad_DIR}) message(STATUS ${Breakpad_SRC}) # TODO this should be properly moved to some BreakpadConfig.cmake find_path(MITK_BREAKPAD_SRC_DIR breakpad_googletest_includes.h DOC "Directory breakpad/src/" PATHS ${Breakpad_SRC}/src ${Breakpad_DIR}) message(STATUS "Found Breakpad at:") message(STATUS ${MITK_BREAKPAD_SRC_DIR}) if(CMAKE_SYSTEM MATCHES "Windows") set(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_BREAKPAD_SRC_DIR}) set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${Breakpad_DIR}/Debug/breakpad_client.lib # ${Breakpad_DIR}/Release/common.lib # ?? # ${Breakpad_DIR}/Release/crash_generation_client.lib # ??? # ${Breakpad_DIR}/Release/crash_generation_server.lib # out-of-process dump generator # ${Breakpad_DIR}/Release/exception_handler.lib # dump creator (ExceptionHandler) # ${Breakpad_DIR}/Release/crash_report_sender.lib ) # ??? unused, I guess set(EXECUTABLE_PROPERTY WIN32) elseif(CMAKE_SYSTEM MATCHES "Linux") set(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_BREAKPAD_SRC_DIR}) # TODO why the repetition, is INCLUDE_DIRS_INTERNAL not empty before?? set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${Breakpad_DIR}/libbreakpad_client.a ) else() message(FATAL_ERROR "Unsupported platform for Breakpad crash reporting: ${CMAKE_SYSTEM}") endif() message(STATUS "Building BreakpadCrashReporting module.") message(STATUS " Including ${INCLUDE_DIRS_INTERNAL}") message(STATUS " Linking ${ADDITIONAL_LIBS}") MITK_CREATE_MODULE(BreakpadCrashReporting INCLUDE_DIRS ${MITK_BIN_DIR} INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} DEPENDS Mitk Qmitk EXPORT_DEFINE MITK_BREAKPAD_EXPORT ADDITIONAL_LIBS ${ADDITIONAL_LIBS} QT_MODULE ) if(CMAKE_SYSTEM MATCHES "Windows") add_executable(CrashReportingServer ${EXECUTABLE_PROPERTY} mitkCrashReportingServer.cpp ${SERVER_MOC_CPP}) target_link_libraries(CrashReportingServer ${ALL_LIBRARIES} ${QT_QTMAIN_LIBRARY} BreakpadCrashReporting) endif() add_subdirectory(Testing) endif(MITK_USE_BREAKPAD) diff --git a/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h b/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h index 3c90928575..13dbc29e7a 100644 --- a/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h +++ b/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h @@ -1,167 +1,156 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITK_BREAKPAD_CRASH_REPORTING_H #define MITK_BREAKPAD_CRASH_REPORTING_H #include "BreakpadCrashReportingExports.h" #include namespace google_breakpad { class ExceptionHandler; class CrashGenerationServer; } namespace mitk { /** - - TODO - oop server Linux - help on how to USE dumps - test dump existence - CMake: - check buildtype (O2/-g/..) - build integration - TODO long-term: Apple - - * \brief Integration of Google's Breakpad Project in MITK. * * Breakpad is a library and tool suite that allows you to distribute an application to users with compiler-provided * debugging information removed, record crashes in compact "minidump" files, send them back to your server, and * produce C and C++ stack traces from these minidumps. Breakpad can also write minidumps on request for programs that * have not crashed (from http://code.google.com/p/google-breakpad/wiki/GettingStartedWithBreakpad). * * * Usage: * * In-process usage: * Instantiate this class, and initialize an event handler for 'unhandled' exceptions by calling * InitializeClientHandler(false). In the event of a crash your application will try to generate a dump file. * * Out-of-process (OOP) usage: * However,your application crashed - therefore using your application's process for dealing with unhandled exceptions is * not safe. Heap and stack may be corrupted. Having a separated process that invoces the generation of a minidump of your process is best, * this is called out-of-process exception handling. * * Sample code for simple OOP usage: * mitk::BreakpadCrashReporting myBreakpad; * myBreakpad.StartCrashServer(true); * [... some code ...] * myBreakpad.InitializeClientHandler(true); * * Note 1: The start of a detached process takes some time. Either you call InitializeClientHandler(true) a while after calling * StartCrashServer(true), or it may take some time and a few connection attempts (configurable, see re-connect handling). * * Note 2: If there is no connection to the server possible, there is an automatic fallback to in-process usage. * Client and server output will indicate the operating mode. * * Note 3: The crash reporting server process will automatically shutdown, if there was a client connected and exits * (either due to shutdown or due to crash). Also, the sample server will shutdown automatically, if there isalready * one server instance running. * */ class MITK_BREAKPAD_EXPORT BreakpadCrashReporting { public: BreakpadCrashReporting(/*TODO add path here*/); ~BreakpadCrashReporting(); /** Initializes an event handler for 'unhandled exceptions' that will dump a so-called 'minidump' to a defined folder. * For usage as "in-process" exception handler set connectToCrashGenerationServer = false. * For usage as "out-of-process" (OOP) exception handler, set connectToCrashGenerationServer = true. * * Related params: * Are defined by means of SetNamedPipeName() and SetCrashDumpPath(). * * OOP Usage: * In OOP use case, the handler uses a crash generation client that connects to a crash generation server via named pipes. * Such a crash generation server should be started then on beforehand by means of the function StartCrashServer() below. * * If the connection attempt to a server fails, reconnects attempt may be scheduled by SetNumberOfConnectionAttempts() * and SetReconnectDelayInMilliSeconds(). Note that during re-connect attempts, your application will be blocked. * * * */ void InitializeClientHandler(bool connectToCrashGenerationServer); /** Starts a crash generation server for "out-of-process" exception handling. * * For usage outside of your main application (i.e. already in a separate process), set launchOutOfProcessExecutable = false. * For usage inside of your main application, set launchOutOfProcessExecutable = true. * * In the latter case, StartCrashServer() will spawn a detached process launching the crash generation server. * This server process will automatically shutdown again, if a once connected client exits due to client shutdown or crash. * * By default, an instance of the sample crash reporting server, mitk::CrashReportingServer will be used. Alternatively, * you may define a process to be started by SetCrashReportingServerExecutable(). * * Related params are defined by means of SetNamedPipeName() and SetCrashDumpPath(). * */ bool StartCrashServer(bool launchOutOfProcessExecutable); // Named pipe string to communicate with OutOfProcessCrashReporter. QString m_NamedPipeString; void SetNamedPipeName(QString name){m_NamedPipeString = name;} // Directory path to save crash dumps. QString m_CrashDumpPath; void SetCrashDumpPath(QString path){m_CrashDumpPath = path;} // External out-of-process (OOP) Crash Reporting Server file path - if OOP is used. QString m_CrashReportingServerExecutable; void SetCrashReportingServerExecutable(QString exe){m_CrashReportingServerExecutable = exe;} // Re-connect handling in case a crash server cannot be reached. void SetNumberOfConnectionAttempts(int no){m_NumberOfConnectionAttempts = no;} void SetReconnectDelayInMilliSeconds(int ms) {m_ReconnectDelay = ms;} int m_NumberOfConnectionAttempts; int m_ReconnectDelay; // This may be a security issue. google_breakpad::ExceptionHandler* m_ExceptionHandler; google_breakpad::CrashGenerationServer* m_CrashServer; // Do not call this without purpose :-) void CrashAppForTestPurpose(); // Writes a minidump immediately. This can be used to capture the // execution state independently of a crash. Returns true on success. bool RequestDump(); // returns the number of currently connected clients int GetNumberOfConnections(); protected: bool InitializeServer(int listen_fd = -1); void StopCrashServer(); bool DumpCallbackPlatformIndependent(); int server_fd; int client_fd; }; } // namespace mitk #endif /* _H_HEADER_INCLUDED_ */