From e12bb3ac7011cfaefb50c647f176fc6dfdd8420b Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 17 Apr 2017 13:39:11 -0400 Subject: [PATCH] Create MiniDump file on Windows in the case of a crash --- apps/OpenSpace/CMakeLists.txt | 2 +- apps/OpenSpace/main.cpp | 87 +++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/apps/OpenSpace/CMakeLists.txt b/apps/OpenSpace/CMakeLists.txt index 1e3deb9801..b0dd03eac9 100644 --- a/apps/OpenSpace/CMakeLists.txt +++ b/apps/OpenSpace/CMakeLists.txt @@ -69,7 +69,7 @@ add_executable(${APPLICATION_NAME} ${RESOURCE_FILE} ) target_include_directories(${APPLICATION_NAME} PUBLIC ${OPENSPACE_BASE_DIR}/include ${OPENVR_INCLUDE_DIRS} ${SGCT_OPENVR_INCLUDE_DIRECTORY}) -target_link_libraries(${APPLICATION_NAME} libOpenSpace ${OPENVR_LIBRARY}) +target_link_libraries(${APPLICATION_NAME} libOpenSpace ${OPENVR_LIBRARY} Dbghelp.lib) target_compile_definitions(${APPLICATION_NAME} PUBLIC ${SGCT_OPENVR_DEFINITIONS}) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 5c31a05fde..7768373196 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -32,6 +32,22 @@ #include +#ifdef WIN32 + +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#endif // WIN32 + #ifdef OPENVR_SUPPORT #include #endif // OPENVR_SUPPORT @@ -43,6 +59,73 @@ namespace { const char* _loggerCat = "main"; sgct::Engine* SgctEngine; + +#ifdef WIN32 + +LONG WINAPI generateMiniDump(EXCEPTION_POINTERS* exceptionPointers) { + SYSTEMTIME stLocalTime; + GetLocalTime(&stLocalTime); + + + LFATAL("Printing Stack Trace that lead to the crash:"); + std::vector stackTrace = ghoul::stackTrace(); + for (const std::string& s : stackTrace) { + LINFO(s); + } + + std::string dumpFile = fmt::format( + "OpenSpace_{}_{}_{}-{}-{}-{}-{}-{}-{}--{}--{}.dmp", + openspace::OPENSPACE_VERSION_MAJOR, + openspace::OPENSPACE_VERSION_MINOR, + openspace::OPENSPACE_VERSION_PATCH, + stLocalTime.wYear, + stLocalTime.wMonth, + stLocalTime.wDay, + stLocalTime.wHour, + stLocalTime.wMinute, + stLocalTime.wSecond, + GetCurrentProcessId(), + GetCurrentThreadId() + ); + + LINFO("Creating dump file: " << dumpFile); + + HANDLE hDumpFile = CreateFile( + dumpFile.c_str(), + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ, + 0, + CREATE_ALWAYS, + 0, + 0 + ); + + MINIDUMP_EXCEPTION_INFORMATION exceptionParameter; + exceptionParameter.ThreadId = GetCurrentThreadId(); + exceptionParameter.ExceptionPointers = exceptionPointers; + exceptionParameter.ClientPointers = TRUE; + + BOOL success = MiniDumpWriteDump( + GetCurrentProcess(), + GetCurrentProcessId(), + hDumpFile, + MiniDumpWithDataSegs, + &exceptionParameter, + nullptr, + nullptr + ); + + if (success) { + LINFO("Created successfully"); + } + else { + LERROR("Dumpfile created unsuccessfully"); + } + + return EXCEPTION_EXECUTE_HANDLER; +} + +#endif // WIN32 #ifdef OPENVR_SUPPORT sgct::SGCTWindow* FirstOpenVRWindow = nullptr; @@ -395,6 +478,10 @@ int main_main(int argc, char** argv) { } // namespace int main(int argc, char** argv) { +#ifdef WIN32 + SetUnhandledExceptionFilter(generateMiniDump); +#endif // WIN32 + // If we are working as a developer, we don't want to catch the exceptions in order to // find the locations where the exceptions are raised. // If we are not in developer mode, we want to catch and at least log the error before