aboutsummaryrefslogtreecommitdiff
path: root/libs/installer_fomod_plus/installer/lib/CrashHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/installer_fomod_plus/installer/lib/CrashHandler.cpp')
-rw-r--r--libs/installer_fomod_plus/installer/lib/CrashHandler.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/libs/installer_fomod_plus/installer/lib/CrashHandler.cpp b/libs/installer_fomod_plus/installer/lib/CrashHandler.cpp
new file mode 100644
index 0000000..98ed1f3
--- /dev/null
+++ b/libs/installer_fomod_plus/installer/lib/CrashHandler.cpp
@@ -0,0 +1,122 @@
+#include "CrashHandler.h"
+#include <iostream>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <dbghelp.h>
+#include <sstream>
+#include <fstream>
+
+LPTOP_LEVEL_EXCEPTION_FILTER CrashHandler::previousFilter = nullptr;
+PVOID CrashHandler::vectoredHandler = nullptr;
+#endif
+
+void CrashHandler::initialize() {
+#ifdef _WIN32
+ std::cout << "CrashHandler initializing..." << std::endl;
+ vectoredHandler = AddVectoredExceptionHandler(1, vectoredExceptionHandler);
+ previousFilter = SetUnhandledExceptionFilter(unhandledExceptionFilter);
+ std::cout << "CrashHandler initialized successfully" << std::endl;
+#else
+ // No-op on Linux — Windows crash handler not needed.
+#endif
+}
+
+void CrashHandler::cleanup() {
+#ifdef _WIN32
+ if (vectoredHandler) {
+ RemoveVectoredExceptionHandler(vectoredHandler);
+ vectoredHandler = nullptr;
+ }
+ if (previousFilter) {
+ SetUnhandledExceptionFilter(previousFilter);
+ previousFilter = nullptr;
+ }
+#endif
+}
+
+#ifdef _WIN32
+LONG WINAPI CrashHandler::vectoredExceptionHandler(EXCEPTION_POINTERS* exceptionInfo) {
+ // Log all exceptions but only create dumps for serious ones
+ std::cout << "Exception caught: 0x" << std::hex << exceptionInfo->ExceptionRecord->ExceptionCode << std::endl;
+
+ // Only create dumps for serious crashes, not benign exceptions
+ if (exceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||
+ exceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW ||
+ exceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION) {
+
+ // For stack overflow, we need to handle it on a different thread with its own stack
+ if (exceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) {
+ // Create a new thread to handle the crash dump since our stack is corrupted
+ HANDLE dumpThread = CreateThread(nullptr, 0, [](LPVOID param) -> DWORD {
+ auto* exceptionInfo = static_cast<EXCEPTION_POINTERS*>(param);
+ logCrashInfo(exceptionInfo);
+
+ HANDLE file = CreateFileA("fomod_plus_stack_overflow.dmp", GENERIC_WRITE, 0, nullptr,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
+
+ if (file != INVALID_HANDLE_VALUE) {
+ MINIDUMP_EXCEPTION_INFORMATION dumpInfo = {0};
+ dumpInfo.ThreadId = GetCurrentThreadId();
+ dumpInfo.ExceptionPointers = exceptionInfo;
+ dumpInfo.ClientPointers = FALSE;
+
+ MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file,
+ MiniDumpNormal, &dumpInfo, nullptr, nullptr);
+ CloseHandle(file);
+
+ std::cout << "Stack overflow crash dump written to fomod_plus_stack_overflow.dmp" << std::endl;
+ }
+ return 0;
+ }, exceptionInfo, 0, nullptr);
+
+ if (dumpThread) {
+ WaitForSingleObject(dumpThread, 5000); // Wait up to 5 seconds
+ CloseHandle(dumpThread);
+ }
+ } else {
+ logCrashInfo(exceptionInfo);
+
+ // Generate minidump
+ HANDLE file = CreateFileA("fomod_plus_crash.dmp", GENERIC_WRITE, 0, nullptr,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
+
+ if (file != INVALID_HANDLE_VALUE) {
+ MINIDUMP_EXCEPTION_INFORMATION dumpInfo = {0};
+ dumpInfo.ThreadId = GetCurrentThreadId();
+ dumpInfo.ExceptionPointers = exceptionInfo;
+ dumpInfo.ClientPointers = FALSE;
+
+ MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file,
+ MiniDumpNormal, &dumpInfo, nullptr, nullptr);
+ CloseHandle(file);
+
+ std::cout << "Crash dump written to fomod_plus_crash.dmp" << std::endl;
+ }
+ }
+ }
+
+ return EXCEPTION_CONTINUE_SEARCH; // Let other handlers process it
+}
+
+LONG WINAPI CrashHandler::unhandledExceptionFilter(EXCEPTION_POINTERS* exceptionInfo) {
+ logCrashInfo(exceptionInfo);
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+void CrashHandler::logCrashInfo(const EXCEPTION_POINTERS* exceptionInfo) {
+ std::ostringstream oss;
+ oss << "FOMOD PLUS CRASH DETECTED!" << std::endl;
+ oss << "Exception Code: 0x" << std::hex << exceptionInfo->ExceptionRecord->ExceptionCode << std::endl;
+ oss << "Exception Address: 0x" << std::hex << exceptionInfo->ExceptionRecord->ExceptionAddress << std::endl;
+
+ // Write to stdout immediately
+ std::cout << oss.str() << std::endl;
+
+ // Also write to crash log file
+ std::ofstream crashLog("fomod_plus_crash.log", std::ios::app);
+ if (crashLog.is_open()) {
+ crashLog << oss.str() << std::endl;
+ }
+}
+#endif