Deregister SEH handler before reporting SE.

This commit is contained in:
Martin Hořeňovský 2017-02-06 20:40:46 +01:00
parent 4feb2dbb50
commit 23600609c0

View File

@ -53,6 +53,7 @@ namespace Catch {
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
reset();
reportFatal(signalDefs[i].name); reportFatal(signalDefs[i].name);
} }
} }
@ -61,22 +62,25 @@ namespace Catch {
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }
// 32k seems enough for Catch to handle stack overflow, FatalConditionHandler() {
// but the value was found experimentally, so there is no strong guarantee isSet = true;
FatalConditionHandler():m_isSet(true), m_guaranteeSize(32 * 1024), m_exceptionHandlerHandle(CATCH_NULL) { // 32k seems enough for Catch to handle stack overflow,
// but the value was found experimentally, so there is no strong guarantee
guaranteeSize = 32 * 1024;
exceptionHandlerHandle = CATCH_NULL;
// Register as first handler in current chain // Register as first handler in current chain
m_exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
// Pass in guarantee size to be filled // Pass in guarantee size to be filled
SetThreadStackGuarantee(&m_guaranteeSize); SetThreadStackGuarantee(&guaranteeSize);
} }
void reset() { static void reset() {
if (m_isSet) { if (isSet) {
// Unregister handler and restore the old guarantee // Unregister handler and restore the old guarantee
RemoveVectoredExceptionHandler(m_exceptionHandlerHandle); RemoveVectoredExceptionHandler(exceptionHandlerHandle);
SetThreadStackGuarantee(&m_guaranteeSize); SetThreadStackGuarantee(&guaranteeSize);
m_exceptionHandlerHandle = CATCH_NULL; exceptionHandlerHandle = CATCH_NULL;
m_isSet = false; isSet = false;
} }
} }
@ -84,11 +88,15 @@ namespace Catch {
reset(); reset();
} }
private: private:
bool m_isSet; static bool isSet;
ULONG m_guaranteeSize; static ULONG guaranteeSize;
PVOID m_exceptionHandlerHandle; static PVOID exceptionHandlerHandle;
}; };
bool FatalConditionHandler::isSet = false;
ULONG FatalConditionHandler::guaranteeSize = 0;
PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
} // namespace Catch } // namespace Catch
# endif // CATCH_CONFIG_WINDOWS_SEH # endif // CATCH_CONFIG_WINDOWS_SEH