diff --git a/Modules/BreakpadCrashReporting/CMakeLists.txt b/Modules/BreakpadCrashReporting/CMakeLists.txt index be019a72af..703f0b64d4 100644 --- a/Modules/BreakpadCrashReporting/CMakeLists.txt +++ b/Modules/BreakpadCrashReporting/CMakeLists.txt @@ -1,44 +1,52 @@ option(MITK_USE_BREAKPAD_CRASH_REPORTING "Enable support for Google Breakpad Crash Reporting" OFF) if(MITK_USE_BREAKPAD_CRASH_REPORTING) if(CMAKE_SYSTEM MATCHES "Windows") find_path(MITK_BREAKPAD_SRC_DIR breakpad_googletest_includes.h ${MITK_BREAKPAD_SRC_DIR} DOC "Directory breakpad/src/") set(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_BREAKPAD_SRC_DIR}) - set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_BREAKPAD_SRC_DIR}/client/windows/Release/lib/common.lib) - set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_BREAKPAD_SRC_DIR}/client/windows/Release/lib/crash_generation_client.lib) - set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_BREAKPAD_SRC_DIR}/client/windows/Release/lib/crash_generation_server.lib) - set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_BREAKPAD_SRC_DIR}/client/windows/Release/lib/exception_handler.lib) - set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_BREAKPAD_SRC_DIR}/client/windows/Release/lib/crash_report_sender.lib) + set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} + ${MITK_BREAKPAD_SRC_DIR}/client/windows/Release/lib/common.lib # ?? + ${MITK_BREAKPAD_SRC_DIR}/client/windows/Release/lib/crash_generation_client.lib # ??? + ${MITK_BREAKPAD_SRC_DIR}/client/windows/Release/lib/crash_generation_server.lib # out-of-process dump generator + ${MITK_BREAKPAD_SRC_DIR}/client/windows/Release/lib/exception_handler.lib # dump creator (ExceptionHandler) + ${MITK_BREAKPAD_SRC_DIR}/client/windows/Release/lib/crash_report_sender.lib + ) # ??? unused, I guess + + set(EXECUTABLE_PROPERTY WIN32) + elseif(CMAKE_SYSTEM MATCHES "Linux") + find_path(MITK_BREAKPAD_SRC_DIR breakpad_googletest_includes.h ${MITK_BREAKPAD_SRC_DIR} DOC "Directory breakpad/src/") + + 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} + ${MITK_BREAKPAD_SRC_DIR}/client/linux/libbreakpad_client.a + ) + else() + message(FATAL_ERROR "Unsupported platform for Breakpad crash reporting: ${CMAKE_SYSTEM}") + endif() - message(INFORMATION "Building BreakpadCrashReporting module.") + message(STATUS "Building BreakpadCrashReporting module.") + message(STATUS " Including ${INCLUDE_DIRS_INTERNAL}") + message(STATUS " Linking ${ADDITIONAL_LIBS}") - MITK_CREATE_MODULE(BreakpadCrashReporting + 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}) - if(WIN32) # crash report server without console window - - # how to create main.moc ?? - #QT4_WRAP_CPP(SERVER_MOC_CPP mitkCrashReportingServer.cpp) - - #use this for windows console: - # add_executable(CrashReportingServer mitkCrashReportingServer.cpp ${SERVER_MOC_CPP}) - add_executable(CrashReportingServer WIN32 mitkCrashReportingServer.cpp ${SERVER_MOC_CPP}) - - target_link_libraries(CrashReportingServer ${ALL_LIBRARIES} ${QT_QTMAIN_LIBRARY} BreakpadCrashReporting) - - endif() - + target_link_libraries(CrashReportingServer ${ALL_LIBRARIES} ${QT_QTMAIN_LIBRARY} BreakpadCrashReporting) endif() +add_subdirectory(Testing) + endif(MITK_USE_BREAKPAD_CRASH_REPORTING) diff --git a/Modules/BreakpadCrashReporting/Testing/CMakeLists.txt b/Modules/BreakpadCrashReporting/Testing/CMakeLists.txt new file mode 100644 index 0000000000..153cd81e2e --- /dev/null +++ b/Modules/BreakpadCrashReporting/Testing/CMakeLists.txt @@ -0,0 +1 @@ +MITK_CREATE_MODULE_TESTS() diff --git a/Modules/BreakpadCrashReporting/Testing/files.cmake b/Modules/BreakpadCrashReporting/Testing/files.cmake new file mode 100644 index 0000000000..1335fd0458 --- /dev/null +++ b/Modules/BreakpadCrashReporting/Testing/files.cmake @@ -0,0 +1,3 @@ +set(MODULE_TESTS + mitkBreakpadCrashReportingDumpTest.cpp +) diff --git a/Modules/BreakpadCrashReporting/Testing/mitkBreakpadCrashReportingDumpTest.cpp b/Modules/BreakpadCrashReporting/Testing/mitkBreakpadCrashReportingDumpTest.cpp new file mode 100644 index 0000000000..9c0dca3c09 --- /dev/null +++ b/Modules/BreakpadCrashReporting/Testing/mitkBreakpadCrashReportingDumpTest.cpp @@ -0,0 +1,47 @@ +/*=================================================================== + +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. + +===================================================================*/ + +#include "mitkTestingMacros.h" + +#include "mitkBreakpadCrashReporting.h" + +#include + +int mitkBreakpadCrashReportingDumpTest(int argc, char** argv) +{ + // always start with this! + MITK_TEST_BEGIN("mitkBreakpadCrashReportingDumpTest") + + QCoreApplication qtApplication(argc,argv); + + mitk::BreakpadCrashReporting crashReporting; + + // start out-of-process crash dump server + MITK_TEST_CONDITION_REQUIRED( crashReporting.StartCrashServer(true) == true, "Start out-of-process crash reporting server"); + + // in-process reporting client (minimal code to tell other process to dump information) + crashReporting.InitializeClientHandler(true); + + MITK_TEST_CONDITION_REQUIRED( true, "Start crash reporting client (in crashing process)"); + + // provoke a seg-fault to make test crash + crashReporting.CrashAppForTestPurpose(); + + MITK_TEST_CONDITION_REQUIRED( false, "Test failed, did not crash...)"); + + // always end with this! + MITK_TEST_END() +} diff --git a/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.cpp b/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.cpp index 1c157714de..28ef7adeb2 100644 --- a/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.cpp +++ b/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.cpp @@ -1,294 +1,419 @@ /*=================================================================== 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. ===================================================================*/ #include "mitkBreakpadCrashReporting.h" #include "mitkLogMacros.h" -#if defined(Q_OS_WIN) +#ifdef Q_OS_WIN + #include #include #include "client/windows/crash_generation/client_info.h" #include "client/windows/crash_generation/crash_generation_server.h" #include "client/windows/handler/exception_handler.h" #include "client/windows/common/ipc_protocol.h" -#elif defined(Q_OS_MAC) +#elif Q_OS_MAC + #include #include #include -#elif defined(Q_OS_LINUX) + +#elif __gnu_linux__ + +#include +#include #include #include #include + #endif #include #include #include #include #include static bool breakpadOnceConnected = false; // indicates a server having had at least one client connection static int breakpadNumberOfConnections = 0; // current number of connected clients static int numberOfConnectionAttemptsPerformed = 1; // number of performed re-connect attempts of a crash client mitk::BreakpadCrashReporting::BreakpadCrashReporting() +:server_fd(-1) +,client_fd(-1) { m_CrashServer = NULL; m_ExceptionHandler = NULL; m_NamedPipeString = "\\\\.\\pipe\\MitkCrashServices\\MitkBasedApplication"; m_CrashDumpPath = QDir(QApplication::instance()->applicationDirPath()).absolutePath(); - m_CrashDumpPath.append("/CrashDumps/"); + m_CrashDumpPath.append("/CrashDumps/"); // is created if it does not exist m_NumberOfConnectionAttempts = 3; m_ReconnectDelay = 300; + // TODO platform specific +#ifdef WIN32 m_CrashReportingServerExecutable = QDir(QApplication::instance()->applicationDirPath()).absolutePath().append("/CrashReportingServer.exe"); +#else + m_CrashReportingServerExecutable = QDir(QApplication::instance()->applicationDirPath()).absolutePath().append("/CrashReportingServer"); +#endif } mitk::BreakpadCrashReporting::~BreakpadCrashReporting() { if (m_ExceptionHandler) { delete m_ExceptionHandler; } if (m_CrashServer) { delete m_CrashServer; } } + +#ifdef WIN32 +// TODO platform specific //This function gets called in the event of a crash. -bool ShowDumpResults(const wchar_t* dump_path, +bool BreakpadCrashReportingDumpCallbackWindows(const wchar_t* dump_path, const wchar_t* minidump_id, void* context, EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion, bool succeeded) { /* NO STACK USE, NO HEAP USE IN THIS FUNCTION Creating QString's, using qDebug, etc. - everything is crash-unfriendly. */ //QMessageBox::information( NULL, "Application problem", "The application encountered an error. \n\n A detailed error report may have been written - contact support.", QMessageBox::Ok ); return succeeded; } +#elif __gnu_linux__ +bool BreakpadCrashReportingDumpCallbackLinux(const google_breakpad::MinidumpDescriptor& descriptor, + void* context, + bool succeeded) +{ + return succeeded; +} +#endif + +bool mitk::BreakpadCrashReporting::DumpCallbackPlatformIndependent() +{ +} void mitk::BreakpadCrashReporting::InitializeClientHandler(bool connectToCrashGenerationServer) { - google_breakpad::CustomClientInfo custom_info; +#ifdef WIN32 // http://stackoverflow.com/questions/5625884/conversion-of-stdwstring-to-qstring-throws-linker-error + std::wstring dump_path = std::wstring((const wchar_t *)m_CrashDumpPath.utf16()); +#else + std::string dump_path = m_CrashDumpPath.toStdString(); +#endif + + +#ifdef WIN32 /* This is needed for CRT to not show dialog for invalid param failures and instead let the code handle it.*/ _CrtSetReportMode(_CRT_ASSERT, 0); const wchar_t* pipe; if(connectToCrashGenerationServer) { pipe = (const wchar_t*)m_NamedPipeString.utf16(); MITK_INFO << "Initializing Breakpad Crash Handler, connecting to named pipe: " << m_NamedPipeString.toStdString().c_str() << "\n"; } else { pipe = (const wchar_t*) L""; MITK_INFO << "Initializing Breakpad Crash Handler, connecting to named pipe: "; } -#ifdef _MSC_VER // http://stackoverflow.com/questions/5625884/conversion-of-stdwstring-to-qstring-throws-linker-error - std::wstring dump_path = std::wstring((const wchar_t *)m_CrashDumpPath.utf16()); -#else - std::wstring dump_path = m_CrashDumpPath.toStdWString(); -#endif - - - m_ExceptionHandler = new google_breakpad::ExceptionHandler( -#if defined(Q_OS_WIN) - dump_path, -#else - m_CrashDumpPath.toStdString(), -#endif + dump_path, + m_CrashDumpPath.toStdString(), NULL, - ShowDumpResults, + BreakpadCrashReportingDumpCallbackWindows, NULL, google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal, //see DbgHelp.h pipe, - &custom_info); + NULL); // custom client info (unused) if(connectToCrashGenerationServer) { if(!m_ExceptionHandler->IsOutOfProcess()) { // we want to connect to a server but connection handler did not connect to OOP server. MITK_INFO << "Initializing Breakpad Crash Handler: connection attempt to crash report server failed. Server started?"; if(numberOfConnectionAttemptsPerformed < this->m_NumberOfConnectionAttempts) { itksys::SystemTools::Delay(m_ReconnectDelay); //sleep a little numberOfConnectionAttemptsPerformed++; InitializeClientHandler(connectToCrashGenerationServer); } else { MITK_INFO << "Initializing Breakpad Crash Handler: connection attempt to crash report server failed - will proceed with in process handler."; } } } + +#elif __gnu_linux__ + + google_breakpad::MinidumpDescriptor dumpDescriptor( dump_path ); + + if (client_fd == -1) + { + MITK_WARN << "In-process crash dump handling, the unsafer method"; + } + + m_ExceptionHandler = new google_breakpad::ExceptionHandler( + dumpDescriptor, // descriptor (where to dump) + NULL, // filter (we don't filter) + BreakpadCrashReportingDumpCallbackLinux, // our callback in cases of crashes + NULL, // callback_context (no idea.. custom data probably) + true, // install_handler (yes, write dumps with each crash, not only on request) + client_fd ); // should be initialized in StopCrashServer() by ealier call + + +#endif } -static void _cdecl ShowClientConnected(void* context, +static void +#ifdef WIN32 + _cdecl +#endif +ShowClientConnected(void* context, const google_breakpad::ClientInfo* client_info) { // callback of the crash generation server on client connect +#ifdef WIN32 MITK_INFO << "Breakpad Client connected: " << client_info->pid(); +#else + MITK_INFO << "Breakpad Client connected: TODO proc-info"; +#endif breakpadOnceConnected = true; // static variables indicate server shutdown after usage breakpadNumberOfConnections++; } -static void _cdecl ShowClientCrashed(void* context, - const google_breakpad::ClientInfo* client_info, - const std::wstring* dump_path) +#ifdef WIN32 +static void _cdecl ShowClientCrashed(void* context, const google_breakpad::ClientInfo* client_info, const std::wstring* dump_path) +#elif __gnu_linux__ +static void ShowClientCrashed(void* context, const google_breakpad::ClientInfo* client_info, const std::string* dump_path) +#endif { // callback of the crash generation server on client crash +#ifdef WIN32 MITK_INFO << "Breakpad Client request dump: " << client_info->pid(); - // we may add some log info here along the dump file google_breakpad::CustomClientInfo custom_info = client_info->GetCustomInfo(); +#else + MITK_INFO << "Breakpad Client request dump: TODO proc-info"; +#endif + } -static void _cdecl ShowClientExited(void* context, +static void +#ifdef WIN32 + _cdecl +#endif +ShowClientExited(void* context, const google_breakpad::ClientInfo* client_info) { // callback of the crash generation server on client exit +#ifdef WIN32 MITK_INFO << "Breakpad Client exited :" << client_info->pid(); +#else + MITK_INFO << "Breakpad Client exited : TODO proc-info"; +#endif // we'd like to shut down server if there is no further client connected, // but no access to private server members in this callback breakpadNumberOfConnections--; if(breakpadNumberOfConnections == 0 && breakpadOnceConnected) { MITK_INFO << "Breakpad Server: no more client connections. Shuting down..."; exit(0); } } bool mitk::BreakpadCrashReporting::StartCrashServer(bool lauchOutOfProcessExecutable) { if (m_CrashServer) { // Do not create another instance of the server. MITK_INFO << "Crash Server object already generated."; return true; } + /* + Idea here: + - application-under-observation starts out-of-process dump generation executable + - dump generation executable creates google CrashGenerationServer + - requires fd to listen to + + DONC + - CreateReportChannel + - fork + - in parent: InitializeServer, exit with return value of qtapplication.exec(), i.e. run forever. TODO stop with crashed child + - in parent: continue + */ + +#ifdef __gnu_linux__ + google_breakpad::CrashGenerationServer::CreateReportChannel(&server_fd, &client_fd); // both OUT parameters + + pid_t child_pid = fork(); + + if ( child_pid != 0) + { + // server process + InitializeServer(server_fd); + + if (qApp) + { + MITK_INFO << "Wait for observed breakpad child to finish/crash..."; + int status; + waitpid( child_pid, &status, WEXITED ); + MITK_INFO << "Breakpad child terminated, so I also terminate..."; + exit(EXIT_SUCCESS); + } + else + { + MITK_ERROR << "You MUST initialize the qApp instance before calling StartCrashServer. You did not. Exiting..."; + exit(EXIT_FAILURE); + } + } + else + { + // child process + return true; // assume we are fine since we got here.. + } + +#endif + if(lauchOutOfProcessExecutable) { // spawn process and launch CrashReportingServer executable QString tmpPipeString = m_NamedPipeString; QString tmpCrashDumpPathString = m_CrashDumpPath; QStringList arguments; arguments << tmpPipeString.prepend('"').append('"'); arguments << tmpCrashDumpPathString.prepend('"').append('"'); bool success = QProcess::startDetached( m_CrashReportingServerExecutable, arguments); return success; } else { // directly open up server instance in this thread return InitializeServer(); } } -bool mitk::BreakpadCrashReporting::InitializeServer() +bool mitk::BreakpadCrashReporting::InitializeServer( int listen_fd ) { QDir myDir; myDir.mkpath(m_CrashDumpPath); // Assure directory is created. -#ifdef _MSC_VER // http://stackoverflow.com/questions/5625884/conversion-of-stdwstring-to-qstring-throws-linker-error - std::wstring dump_path = std::wstring((const wchar_t *)m_CrashDumpPath.utf16()); -#else - std::wstring dump_path = m_CrashDumpPath.toStdWString(); -#endif + google_breakpad::CrashGenerationServer::OnClientDumpRequestCallback dump_callback = &ShowClientCrashed; + google_breakpad::CrashGenerationServer::OnClientExitingCallback exit_callback = &ShowClientExited; + void* dump_context = NULL; + void* exit_context = NULL; - m_CrashServer = new google_breakpad::CrashGenerationServer((const wchar_t*)m_NamedPipeString.utf16(), +#ifdef WIN32 // http://stackoverflow.com/questions/5625884/conversion-of-stdwstring-to-qstring-throws-linker-error + std::wstring dump_path = std::wstring((const wchar_t *)m_CrashDumpPath.utf16()); + m_CrashServer = new google_breakpad::CrashGenerationServer(dump_path, NULL, ShowClientConnected, // connect callback NULL, - ShowClientCrashed, // dump callback - NULL, - ShowClientExited, // exit callback - NULL, + dump_callback, + dump_context, + exit_callback, // exit callback + exit_context, NULL, NULL, true, &dump_path); +#elif __gnu_linux__ + std::string dump_path = m_CrashDumpPath.toStdString(); + + MITK_INFO << "Start Breakpad crash dump generation server with file descriptor " << listen_fd; + + m_CrashServer = new google_breakpad::CrashGenerationServer(listen_fd, + dump_callback, + dump_context, + exit_callback, + exit_context, + true, // generate_dumps + &dump_path); +#endif if (!m_CrashServer->Start()) { - MITK_ERROR << "Unable to start google breakpad server."; + MITK_ERROR << "Unable to start Breakpad crash dump generation server."; delete m_CrashServer; m_CrashServer = NULL; return false; } else { - MITK_INFO << "Google breakpad server started."; + MITK_INFO << "Breakpad crash dump generation server started."; return true; } + + return false; + } bool mitk::BreakpadCrashReporting::RequestDump() { if(this->m_ExceptionHandler != NULL) { if(m_ExceptionHandler->WriteMinidump()) { MITK_INFO << "Breakpad Crash Reporting: Successfully requested a minidump."; return true; } else { MITK_INFO << "Breakpad Crash Reporting: Requested of minidump failed."; return false; } } return false; } void mitk::BreakpadCrashReporting::StopCrashServer() { delete m_CrashServer; m_CrashServer = NULL; } void mitk::BreakpadCrashReporting::CrashAppForTestPurpose() { - //printf(NULL); - - //derived derived; - int* x = 0; *x = 1; } int mitk::BreakpadCrashReporting::GetNumberOfConnections() { return breakpadNumberOfConnections; } diff --git a/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h b/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h index 9c51a716c4..3c90928575 100644 --- a/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h +++ b/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h @@ -1,150 +1,167 @@ /*=================================================================== 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(); + 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(); + bool InitializeServer(int listen_fd = -1); void StopCrashServer(); + + bool DumpCallbackPlatformIndependent(); + + int server_fd; + int client_fd; + }; } // namespace mitk #endif /* _H_HEADER_INCLUDED_ */