1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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
|