diff --git a/Modules/BreakpadCrashReporting/CMakeLists.txt b/Modules/BreakpadCrashReporting/CMakeLists.txt new file mode 100644 index 0000000000..c4fda751f8 --- /dev/null +++ b/Modules/BreakpadCrashReporting/CMakeLists.txt @@ -0,0 +1,29 @@ +option(MITK_USE_BREAKPAD_CRASH_REPORTING "Enable support for Google Breakpad Crash Reporting" ON) + + +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) + + message(INFORMATION "Building BreakpadCrashReporting module.") + + 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 + ) + + endif() + +endif(MITK_USE_BREAKPAD_CRASH_REPORTING) diff --git a/Modules/BreakpadCrashReporting/files.cmake b/Modules/BreakpadCrashReporting/files.cmake new file mode 100644 index 0000000000..291ff72be0 --- /dev/null +++ b/Modules/BreakpadCrashReporting/files.cmake @@ -0,0 +1,3 @@ +set(CPP_FILES + mitkBreakpadCrashReporting.cpp +) diff --git a/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.cpp b/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.cpp new file mode 100644 index 0000000000..d175386cf2 --- /dev/null +++ b/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.cpp @@ -0,0 +1,170 @@ +/*=================================================================== + +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" + +#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" + +#include +#include + +mitk::BreakpadCrashReporting::BreakpadCrashReporting() +{ + m_CrashServer = NULL; + m_ExceptionHandler = NULL; + + m_NamedPipeString = "\\\\.\\pipe\\BreakpadCrashServices\\TestServer"; + m_CrashDumpPath = QDir(QApplication::instance()->applicationDirPath()).filePath("CrashDumps"); +} + +mitk::BreakpadCrashReporting::~BreakpadCrashReporting() +{ + if (m_ExceptionHandler) + { + delete m_ExceptionHandler; + } + + if (m_CrashServer) + { + delete m_CrashServer; + } + +} + +bool ShowDumpResults(const wchar_t* dump_path, + const wchar_t* minidump_id, + void* context, + EXCEPTION_POINTERS* exinfo, + MDRawAssertionInfo* assertion, + bool succeeded) +{ + /*if(succeeded) + MITK_INFO << "Dump generation request result succeeded."; + else + MITK_INFO << "Dump generation request result failed."; + return succeeded;*/ + return succeeded; +} + + +void mitk::BreakpadCrashReporting::Initialize() +{ + //std::wstring dumpPath = this->m_CrashDumpPath.toStdWString(); + + google_breakpad::CustomClientInfo custom_info; + + StartCrashServer(); + + /* 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 kPipeName[] = L"\\\\.\\pipe\\BreakpadCrashServices\\TestServer"; + m_ExceptionHandler = new google_breakpad::ExceptionHandler(L"C:\\dumps\\", + NULL, + ShowDumpResults, + NULL, + google_breakpad::ExceptionHandler::HANDLER_ALL, + MiniDumpNormal, //see DbgHelp.h + kPipeName, + &custom_info); + +} + +static void _cdecl ShowClientConnected(void* context, + const google_breakpad::ClientInfo* client_info) +{ + MITK_INFO << "Breakpad Client connected: " << client_info->pid(); +} + +static void _cdecl ShowClientCrashed(void* context, + const google_breakpad::ClientInfo* client_info, + const std::wstring* dump_path) +{ + + MITK_INFO << "Breakpad Client request dump: " << client_info->pid(); + + google_breakpad::CustomClientInfo custom_info = client_info->GetCustomInfo(); + if (custom_info.count <= 0) + { + return; + } +} + +static void _cdecl ShowClientExited(void* context, + const google_breakpad::ClientInfo* client_info) +{ + MITK_INFO << "Breakpad Client exited :" << client_info->pid(); +} + +void mitk::BreakpadCrashReporting::StartCrashServer() +{ + // Do not create another instance of the server. + if (m_CrashServer) + { + return; + } + + std::wstring dump_path = L"C:\\Dumps\\"; + const wchar_t kPipeName[] = L"\\\\.\\pipe\\BreakpadCrashServices\\TestServer"; + m_CrashServer = new google_breakpad::CrashGenerationServer(kPipeName, + NULL, + ShowClientConnected, + NULL, + ShowClientCrashed, + NULL, + ShowClientExited, + NULL, + NULL, + NULL, + true, + &dump_path); + + if (!m_CrashServer->Start()) + { + MITK_ERROR << "Unable to start google breakpad server."; + delete m_CrashServer; + m_CrashServer = NULL; + } + else + { + MITK_INFO << "Google breakpad server started."; + } +} + +void mitk::BreakpadCrashReporting::StopCrashServer() +{ + delete m_CrashServer; + m_CrashServer = NULL; +} + +void mitk::BreakpadCrashReporting::CrashAppForTestPurpose() +{ + //printf(NULL); + + //derived derived; + + int* x = 0; + *x = 1; +} diff --git a/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h b/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h new file mode 100644 index 0000000000..4d9e0deaf6 --- /dev/null +++ b/Modules/BreakpadCrashReporting/mitkBreakpadCrashReporting.h @@ -0,0 +1,66 @@ +/*=================================================================== + +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 +#include + + +namespace google_breakpad { + + class ExceptionHandler; + class CrashGenerationServer; +} + +namespace mitk { + + /** + * \brief Prototype for using Google's Breakpad Project in MITK. + */ + class MITK_BREAKPAD_EXPORT BreakpadCrashReporting + { + public: + BreakpadCrashReporting(); + ~BreakpadCrashReporting(); + void Initialize(); + + // named pipe string to communicate with OutOfProcessCrashReporter. + QString m_NamedPipeString; + + // QString directory path to save crash dumps. + QString m_CrashDumpPath; + + mutable QMutex m_CriticalSection; + + google_breakpad::ExceptionHandler* m_ExceptionHandler; + google_breakpad::CrashGenerationServer* m_CrashServer; + + void CrashAppForTestPurpose(); + + void RequestDump(); + protected: + void StartCrashServer(); + void StopCrashServer(); + + + }; +} // namespace mitk + +#endif /* _H_HEADER_INCLUDED_ */ diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt index 3943c52f02..93d8d43421 100644 --- a/Modules/CMakeLists.txt +++ b/Modules/CMakeLists.txt @@ -1,65 +1,66 @@ set(LIBPOSTFIX "Ext") # Modules must be listed according to their dependencies set(module_dirs SeedsImage SceneSerializationBase PlanarFigure ImageExtraction ImageStatistics LegacyAdaptors IpPicSupport MitkExt SceneSerialization GraphAlgorithms SurfaceInterpolation Segmentation PlanarFigureSegmentation Qmitk QmitkExt SegmentationUI Properties DiffusionImaging GPGPU IGT CameraCalibration IGTUI RigidRegistration RigidRegistrationUI DeformableRegistration DeformableRegistrationUI OpenCL OpenCVVideoSupport Overlays InputDevices ToFHardware ToFProcessing ToFUI US ClippingTools USUI DicomUI Simulation Remeshing Python + BreakpadCrashReporting ) set(MITK_DEFAULT_SUBPROJECTS MITK-Modules) foreach(module_dir ${module_dirs}) add_subdirectory(${module_dir}) endforeach() if(MITK_PRIVATE_MODULES) file(GLOB all_subdirs RELATIVE ${MITK_PRIVATE_MODULES} ${MITK_PRIVATE_MODULES}/*) foreach(subdir ${all_subdirs}) string(FIND ${subdir} "." _result) if(_result EQUAL -1) if(EXISTS ${MITK_PRIVATE_MODULES}/${subdir}/CMakeLists.txt) message(STATUS "Found private module ${subdir}") add_subdirectory(${MITK_PRIVATE_MODULES}/${subdir} private_modules/${subdir}) endif() endif() endforeach() endif(MITK_PRIVATE_MODULES)