mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-04 05:59:32 +01:00 
			
		
		
		
	Fix issue with Address Sanitizer on Windows.
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user