PrusaSlicer/src/libslic3r/TryCatchSignalSEH.cpp
2023-09-01 14:49:07 +02:00

48 lines
1.4 KiB
C++

///|/ Copyright (c) Prusa Research 2021 Tomáš Mészáros @tamasmeszaros
///|/
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
///|/
#include "TryCatchSignalSEH.hpp"
#include <windows.h>
static int signal_seh_filter(int sigcnt, const Slic3r::SignalT *sigs,
unsigned long seh_code)
{
int ret = EXCEPTION_CONTINUE_SEARCH;
for (int s = 0; s < sigcnt && ret != EXCEPTION_EXECUTE_HANDLER; ++s)
switch (sigs[s]) {
case SIGSEGV:
if (seh_code == STATUS_ACCESS_VIOLATION)
ret = EXCEPTION_EXECUTE_HANDLER;
break;
case SIGILL:
if (seh_code == STATUS_ILLEGAL_INSTRUCTION)
ret = EXCEPTION_EXECUTE_HANDLER;
break;
case SIGFPE:
if (seh_code == STATUS_FLOAT_DIVIDE_BY_ZERO ||
seh_code == STATUS_FLOAT_OVERFLOW ||
seh_code == STATUS_FLOAT_UNDERFLOW ||
seh_code == STATUS_INTEGER_DIVIDE_BY_ZERO)
ret = EXCEPTION_EXECUTE_HANDLER;
break;
default: ret = EXCEPTION_CONTINUE_SEARCH;
}
return ret;
}
void Slic3r::detail::try_catch_signal_seh(int sigcnt, const SignalT *sigs,
std::function<void()> &&fn,
std::function<void()> &&cfn)
{
__try {
fn();
}
__except(signal_seh_filter(sigcnt, sigs, GetExceptionCode())) {
cfn();
}
}