Merge pull request #110 from patchzyy/Color-profile-crash-fix

Refine SEH crash handling on Windows
This commit is contained in:
patchzyy
2026-08-31 16:32:18 +02:00
committed by GitHub
+25 -2
View File
@@ -921,6 +921,7 @@ constexpr DWORD kCppExceptionCodeMsvc = 0xE06D7363;
// AddressSanitizer uses STATUS_FATAL_APP_EXIT when it detects an error and wants to report it.
// We must let ASan's handler run so it can print file/line information.
constexpr DWORD kAsanFatalAppExit = 0x40000015; // STATUS_FATAL_APP_EXIT
LONG ReportFatalSehAndExit(EXCEPTION_POINTERS* info);
void ReportStructuredException(EXCEPTION_POINTERS* info) {
if (!info || !info->ExceptionRecord) {
@@ -1022,13 +1023,34 @@ LONG CALLBACK SehLogger(EXCEPTION_POINTERS* info) {
info->ExceptionRecord->ExceptionCode == kAsanFatalAppExit) { // ASan reporting - let it print first
return EXCEPTION_CONTINUE_SEARCH;
}
// Software-raised exceptions (customer bit set) are used for internal control flow by
// system DLLs (e.g. msxml6 while mscms parses a display colour profile) and are caught
// by their own frame handlers. Only hardware faults are fatal at first chance; anything
// else that truly goes unhandled reaches UnhandledSehFilter.
if ((info->ExceptionRecord->ExceptionCode & 0x20000000u) != 0) {
return EXCEPTION_CONTINUE_SEARCH;
}
return ReportFatalSehAndExit(info);
}
LONG WINAPI UnhandledSehFilter(EXCEPTION_POINTERS* info) {
if (info == nullptr || info->ExceptionRecord == nullptr) {
return EXCEPTION_CONTINUE_SEARCH;
}
const DWORD code = info->ExceptionRecord->ExceptionCode;
if (code == kCppExceptionCodeGcc || code == kCppExceptionCodeMsvc || code == kAsanFatalAppExit) {
return EXCEPTION_CONTINUE_SEARCH;
}
return ReportFatalSehAndExit(info);
}
LONG ReportFatalSehAndExit(EXCEPTION_POINTERS* info) {
// Guard against re-entrancy: if we crash while reporting, don't recurse
static std::atomic_flag s_inCrashHandler = ATOMIC_FLAG_INIT;
if (s_inCrashHandler.test_and_set()) {
std::_Exit(EXIT_FAILURE);
}
// Report the structured exception with detailed information
ReportStructuredException(info);
const auto* record = info->ExceptionRecord;
@@ -1063,6 +1085,7 @@ LONG CALLBACK SehLogger(EXCEPTION_POINTERS* info) {
void InstallSehLogger() {
if (!g_vectoredSehHandle) {
g_vectoredSehHandle = AddVectoredExceptionHandler(1, SehLogger);
SetUnhandledExceptionFilter(UnhandledSehFilter);
}
}
#else