Fix issue with Address Sanitizer on Windows.

This commit is contained in:
Scott Hutchinson 2022-11-25 13:44:01 -08:00
parent 428a30ebd0
commit 2552ed064f
2 changed files with 39 additions and 10 deletions

View File

@ -85,7 +85,7 @@ namespace Catch {
{ static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
};
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
static LONG CALLBACK topLevelExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) {
for (auto const& def : signalDefs) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
reportFatal(def.name);
@ -99,7 +99,7 @@ namespace Catch {
// Since we do not support multiple instantiations, we put these
// into global variables and rely on cleaning them up in outlined
// constructors/destructors
static PVOID exceptionHandlerHandle = nullptr;
static LPTOP_LEVEL_EXCEPTION_FILTER previousTopLevelExceptionFilter = nullptr;
// For MSVC, we reserve part of the stack memory for handling
@ -121,18 +121,15 @@ namespace Catch {
void FatalConditionHandler::engage_platform() {
// Register as first handler in current chain
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
if (!exceptionHandlerHandle) {
CATCH_RUNTIME_ERROR("Could not register vectored exception handler");
}
// Register as a the top level exception filter.
previousTopLevelExceptionFilter = SetUnhandledExceptionFilter(topLevelExceptionFilter);
}
void FatalConditionHandler::disengage_platform() {
if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler");
if (SetUnhandledExceptionFilter(reinterpret_cast<LPTOP_LEVEL_EXCEPTION_FILTER>(previousTopLevelExceptionFilter)) != topLevelExceptionFilter) {
CATCH_RUNTIME_ERROR("Could not restore previous top level exception filter");
}
exceptionHandlerHandle = nullptr;
previousTopLevelExceptionFilter = nullptr;
}
} // end namespace Catch

View File

@ -7,6 +7,7 @@
*/
#include "catch.hpp"
#include <catch2/internal/catch_windows_h_proxy.hpp>
#ifdef __clang__
# pragma clang diagnostic ignored "-Wc++98-compat"
@ -491,3 +492,34 @@ TEMPLATE_TEST_CASE_SIG("#1954 - 7 arg template test case sig compiles", "[regres
}
}} // namespace MiscTests
#if defined(CATCH_PLATFORM_WINDOWS)
void throw_and_catch()
{
__try {
RaiseException(0xC0000005, 0, 0, NULL);
}
__except (1)
{
}
}
TEST_CASE("Validate SEH behavior - handled", "[approvals][FatalConditionHandler][CATCH_PLATFORM_WINDOWS]")
{
// Validate that Catch2 framework correctly handles tests raising and handling SEH exceptions.
throw_and_catch();
}
void throw_no_catch()
{
RaiseException(0xC0000005, 0, 0, NULL);
}
TEST_CASE("Validate SEH behavior - unhandled", "[.approvals][FatalConditionHandler][CATCH_PLATFORM_WINDOWS]")
{
// Validate that Catch2 framework correctly handles tests raising and not handling SEH exceptions.
throw_no_catch();
}
#endif