|
|
@@ -1,6 +1,6 @@
|
|
|
/*
|
|
|
* Catch v1.12.2
|
|
|
- * Generated: 2018-05-14 15:10:01.112442
|
|
|
+ * Generated: 2023-01-17 08:45:40.979381
|
|
|
* ----------------------------------------------------------
|
|
|
* This file has been merged from multiple headers. Please don't edit it directly
|
|
|
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
|
|
|
@@ -214,7 +214,7 @@
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// Use variadic macros if the compiler supports them
|
|
|
-#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
|
|
|
+#if ( defined _MSC_VER && _MSC_VER >= 1400 && !defined __EDGE__) || \
|
|
|
( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
|
|
|
( defined __GNUC__ && __GNUC__ >= 3 ) || \
|
|
|
( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
|
|
|
@@ -2129,6 +2129,9 @@ namespace Catch{
|
|
|
#define CATCH_TRAP() \
|
|
|
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
|
|
: : : "memory","r0","r3","r4" ) /* NOLINT */
|
|
|
+ #elif defined(__aarch64__)
|
|
|
+ // Backport of https://github.com/catchorg/Catch2/commit/a25c1a24af8bffd35727a888a307ff0280cf9387
|
|
|
+ #define CATCH_TRAP() __asm__(".inst 0xd4200000")
|
|
|
#else
|
|
|
#define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
|
|
|
#endif
|
|
|
@@ -6392,18 +6395,21 @@ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
|
|
// #included from: catch_fatal_condition.hpp
|
|
|
#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
|
|
|
|
|
+#include <cassert>
|
|
|
+#include <stdexcept>
|
|
|
+
|
|
|
namespace Catch {
|
|
|
|
|
|
- // Report the error condition
|
|
|
- inline void reportFatal( std::string const& message ) {
|
|
|
- IContext& context = Catch::getCurrentContext();
|
|
|
- IResultCapture* resultCapture = context.getResultCapture();
|
|
|
- resultCapture->handleFatalErrorCondition( message );
|
|
|
- }
|
|
|
+//! Signals fatal error message to the run context
|
|
|
+inline void reportFatal(std::string const &message) {
|
|
|
+ IContext &context = Catch::getCurrentContext();
|
|
|
+ IResultCapture *resultCapture = context.getResultCapture();
|
|
|
+ resultCapture->handleFatalErrorCondition(message);
|
|
|
+}
|
|
|
|
|
|
} // namespace Catch
|
|
|
|
|
|
-#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
|
|
+#if defined(CATCH_PLATFORM_WINDOWS) /////////////////////////////////////////
|
|
|
// #included from: catch_windows_h_proxy.h
|
|
|
|
|
|
#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
|
|
|
@@ -6429,176 +6435,307 @@ namespace Catch {
|
|
|
#endif
|
|
|
|
|
|
|
|
|
-# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
|
|
|
+#if !defined(CATCH_CONFIG_WINDOWS_SEH)
|
|
|
|
|
|
namespace Catch {
|
|
|
- struct FatalConditionHandler {
|
|
|
- void reset() {}
|
|
|
- };
|
|
|
-}
|
|
|
+class FatalConditionHandler {
|
|
|
+ bool m_started;
|
|
|
+
|
|
|
+ // Install/disengage implementation for specific platform.
|
|
|
+ // Should be if-defed to work on current platform, can assume
|
|
|
+ // engage-disengage 1:1 pairing.
|
|
|
+ void engage_platform() {}
|
|
|
+ void disengage_platform() {}
|
|
|
+
|
|
|
+public:
|
|
|
+ // Should also have platform-specific implementations as needed
|
|
|
+ FatalConditionHandler() : m_started(false) {}
|
|
|
+ ~FatalConditionHandler() {}
|
|
|
+
|
|
|
+ void engage() {
|
|
|
+ assert(!m_started && "Handler cannot be installed twice.");
|
|
|
+ m_started = true;
|
|
|
+ engage_platform();
|
|
|
+ }
|
|
|
+
|
|
|
+ void disengage() {
|
|
|
+ assert(m_started &&
|
|
|
+ "Handler cannot be uninstalled without being installed first");
|
|
|
+ m_started = false;
|
|
|
+ disengage_platform();
|
|
|
+ }
|
|
|
+};
|
|
|
+} // namespace Catch
|
|
|
|
|
|
-# else // CATCH_CONFIG_WINDOWS_SEH is defined
|
|
|
+#else // CATCH_CONFIG_WINDOWS_SEH is defined
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
- struct SignalDefs { DWORD id; const char* name; };
|
|
|
- extern SignalDefs signalDefs[];
|
|
|
- // There is no 1-1 mapping between signals and windows exceptions.
|
|
|
- // Windows can easily distinguish between SO and SigSegV,
|
|
|
- // but SigInt, SigTerm, etc are handled differently.
|
|
|
- SignalDefs signalDefs[] = {
|
|
|
- { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
|
|
|
- { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
|
|
|
- { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
|
|
|
- { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
|
|
|
- };
|
|
|
+struct SignalDefs {
|
|
|
+ DWORD id;
|
|
|
+ const char *name;
|
|
|
+};
|
|
|
+extern SignalDefs signalDefs[];
|
|
|
+// There is no 1-1 mapping between signals and windows exceptions.
|
|
|
+// Windows can easily distinguish between SO and SigSegV,
|
|
|
+// but SigInt, SigTerm, etc are handled differently.
|
|
|
+SignalDefs signalDefs[] = {
|
|
|
+ {EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal"},
|
|
|
+ {EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow"},
|
|
|
+ {EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal"},
|
|
|
+ {EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error"},
|
|
|
+};
|
|
|
|
|
|
- struct FatalConditionHandler {
|
|
|
+static LONG CALLBACK
|
|
|
+handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
|
|
+ for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
|
|
+ if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
|
|
+ reportFatal(signalDefs[i].name);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // If its not an exception we care about, pass it along.
|
|
|
+ // This stops us from eating debugger breaks etc.
|
|
|
+ return EXCEPTION_CONTINUE_SEARCH;
|
|
|
+}
|
|
|
|
|
|
- static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
|
|
- for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
|
|
- if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
|
|
- reportFatal(signalDefs[i].name);
|
|
|
- }
|
|
|
- }
|
|
|
- // If its not an exception we care about, pass it along.
|
|
|
- // This stops us from eating debugger breaks etc.
|
|
|
- return EXCEPTION_CONTINUE_SEARCH;
|
|
|
- }
|
|
|
+// 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 = CATCH_NULL;
|
|
|
|
|
|
- FatalConditionHandler() {
|
|
|
- isSet = true;
|
|
|
- // 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
|
|
|
- exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
|
|
- // Pass in guarantee size to be filled
|
|
|
- SetThreadStackGuarantee(&guaranteeSize);
|
|
|
- }
|
|
|
+class FatalConditionHandler {
|
|
|
+ bool m_started;
|
|
|
|
|
|
- static void reset() {
|
|
|
- if (isSet) {
|
|
|
- // Unregister handler and restore the old guarantee
|
|
|
- RemoveVectoredExceptionHandler(exceptionHandlerHandle);
|
|
|
- SetThreadStackGuarantee(&guaranteeSize);
|
|
|
- exceptionHandlerHandle = CATCH_NULL;
|
|
|
- isSet = false;
|
|
|
- }
|
|
|
- }
|
|
|
+ // Install/disengage implementation for specific platform.
|
|
|
+ // Should be if-defed to work on current platform, can assume
|
|
|
+ // engage-disengage 1:1 pairing.
|
|
|
|
|
|
- ~FatalConditionHandler() {
|
|
|
- reset();
|
|
|
- }
|
|
|
- private:
|
|
|
- static bool isSet;
|
|
|
- static ULONG guaranteeSize;
|
|
|
- static PVOID exceptionHandlerHandle;
|
|
|
- };
|
|
|
+ void engage_platform() {
|
|
|
+ // Register as first handler in current chain
|
|
|
+ exceptionHandlerHandle =
|
|
|
+ AddVectoredExceptionHandler(1, handleVectoredException);
|
|
|
+ if (!exceptionHandlerHandle) {
|
|
|
+ throw std::runtime_error("Could not register vectored exception handler");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void disengage_platform() {
|
|
|
+ if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
|
|
|
+ throw std::runtime_error(
|
|
|
+ "Could not unregister vectored exception handler");
|
|
|
+ }
|
|
|
+ exceptionHandlerHandle = CATCH_NULL;
|
|
|
+ }
|
|
|
|
|
|
- bool FatalConditionHandler::isSet = false;
|
|
|
- ULONG FatalConditionHandler::guaranteeSize = 0;
|
|
|
- PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
|
|
|
+public:
|
|
|
+ FatalConditionHandler() : m_started(false) {
|
|
|
+ ULONG guaranteeSize = static_cast<ULONG>(32 * 1024);
|
|
|
+ if (!SetThreadStackGuarantee(&guaranteeSize)) {
|
|
|
+ // We do not want to fully error out, because needing
|
|
|
+ // the stack reserve should be rare enough anyway.
|
|
|
+ Catch::cerr() << "Failed to reserve piece of stack."
|
|
|
+ << " Stack overflows will not be reported successfully.";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // We do not attempt to unset the stack guarantee, because
|
|
|
+ // Windows does not support lowering the stack size guarantee.
|
|
|
+ ~FatalConditionHandler() {}
|
|
|
+
|
|
|
+ void engage() {
|
|
|
+ assert(!m_started && "Handler cannot be installed twice.");
|
|
|
+ m_started = true;
|
|
|
+ engage_platform();
|
|
|
+ }
|
|
|
+
|
|
|
+ void disengage() {
|
|
|
+ assert(m_started &&
|
|
|
+ "Handler cannot be uninstalled without being installed first");
|
|
|
+ m_started = false;
|
|
|
+ disengage_platform();
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
} // namespace Catch
|
|
|
|
|
|
-# endif // CATCH_CONFIG_WINDOWS_SEH
|
|
|
+#endif // CATCH_CONFIG_WINDOWS_SEH
|
|
|
|
|
|
#else // Not Windows - assumed to be POSIX compatible //////////////////////////
|
|
|
|
|
|
-# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
|
|
+#if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
|
|
|
|
|
namespace Catch {
|
|
|
- struct FatalConditionHandler {
|
|
|
- void reset() {}
|
|
|
- };
|
|
|
-}
|
|
|
+class FatalConditionHandler {
|
|
|
+ bool m_started;
|
|
|
|
|
|
-# else // CATCH_CONFIG_POSIX_SIGNALS is defined
|
|
|
+ // Install/disengage implementation for specific platform.
|
|
|
+ // Should be if-defed to work on current platform, can assume
|
|
|
+ // engage-disengage 1:1 pairing.
|
|
|
+ void engage_platform() {}
|
|
|
+ void disengage_platform() {}
|
|
|
+
|
|
|
+public:
|
|
|
+ // Should also have platform-specific implementations as needed
|
|
|
+ FatalConditionHandler() : m_started(false) {}
|
|
|
+ ~FatalConditionHandler() {}
|
|
|
+
|
|
|
+ void engage() {
|
|
|
+ assert(!m_started && "Handler cannot be installed twice.");
|
|
|
+ m_started = true;
|
|
|
+ engage_platform();
|
|
|
+ }
|
|
|
+
|
|
|
+ void disengage() {
|
|
|
+ assert(m_started &&
|
|
|
+ "Handler cannot be uninstalled without being installed first");
|
|
|
+ m_started = false;
|
|
|
+ disengage_platform();
|
|
|
+ }
|
|
|
+};
|
|
|
+} // namespace Catch
|
|
|
+
|
|
|
+#else // CATCH_CONFIG_POSIX_SIGNALS is defined
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
|
namespace Catch {
|
|
|
|
|
|
- struct SignalDefs {
|
|
|
- int id;
|
|
|
- const char* name;
|
|
|
- };
|
|
|
- extern SignalDefs signalDefs[];
|
|
|
- SignalDefs signalDefs[] = {
|
|
|
- { SIGINT, "SIGINT - Terminal interrupt signal" },
|
|
|
- { SIGILL, "SIGILL - Illegal instruction signal" },
|
|
|
- { SIGFPE, "SIGFPE - Floating point error signal" },
|
|
|
- { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
|
|
|
- { SIGTERM, "SIGTERM - Termination request signal" },
|
|
|
- { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
|
|
|
- };
|
|
|
-
|
|
|
- struct FatalConditionHandler {
|
|
|
-
|
|
|
- static bool isSet;
|
|
|
- static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)];
|
|
|
- static stack_t oldSigStack;
|
|
|
- static char altStackMem[SIGSTKSZ];
|
|
|
-
|
|
|
- static void handleSignal( int sig ) {
|
|
|
- std::string name = "<unknown signal>";
|
|
|
- for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
|
|
- SignalDefs &def = signalDefs[i];
|
|
|
- if (sig == def.id) {
|
|
|
- name = def.name;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- reset();
|
|
|
- reportFatal(name);
|
|
|
- raise( sig );
|
|
|
- }
|
|
|
+struct SignalDefs {
|
|
|
+ int id;
|
|
|
+ const char *name;
|
|
|
+};
|
|
|
+extern SignalDefs signalDefs[];
|
|
|
+SignalDefs signalDefs[] = {
|
|
|
+ {SIGINT, "SIGINT - Terminal interrupt signal"},
|
|
|
+ {SIGILL, "SIGILL - Illegal instruction signal"},
|
|
|
+ {SIGFPE, "SIGFPE - Floating point error signal"},
|
|
|
+ {SIGSEGV, "SIGSEGV - Segmentation violation signal"},
|
|
|
+ {SIGTERM, "SIGTERM - Termination request signal"},
|
|
|
+ {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}};
|
|
|
+
|
|
|
+// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
|
|
|
+// which is zero initialization, but not explicit. We want to avoid
|
|
|
+// that.
|
|
|
+#if defined(__GNUC__)
|
|
|
+#pragma GCC diagnostic push
|
|
|
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
|
|
+#endif
|
|
|
+
|
|
|
+static char *altStackMem = CATCH_NULL;
|
|
|
+static std::size_t altStackSize = 0;
|
|
|
+static stack_t oldSigStack;
|
|
|
+static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)];
|
|
|
+
|
|
|
+static void restorePreviousSignalHandlers() {
|
|
|
+ // We set signal handlers back to the previous ones. Hopefully
|
|
|
+ // nobody overwrote them in the meantime, and doesn't expect
|
|
|
+ // their signal handlers to live past ours given that they
|
|
|
+ // installed them after ours..
|
|
|
+ for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
|
|
+ sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
|
|
|
+ }
|
|
|
+ // Return the old stack
|
|
|
+ sigaltstack(&oldSigStack, CATCH_NULL);
|
|
|
+}
|
|
|
|
|
|
- FatalConditionHandler() {
|
|
|
- isSet = true;
|
|
|
- stack_t sigStack;
|
|
|
- sigStack.ss_sp = altStackMem;
|
|
|
- sigStack.ss_size = SIGSTKSZ;
|
|
|
- sigStack.ss_flags = 0;
|
|
|
- sigaltstack(&sigStack, &oldSigStack);
|
|
|
- struct sigaction sa = { 0 };
|
|
|
+static void handleSignal(int sig) {
|
|
|
+ char const *name = "<unknown signal>";
|
|
|
+ for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
|
|
+ SignalDefs &def = signalDefs[i];
|
|
|
+ if (sig == def.id) {
|
|
|
+ name = def.name;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // We need to restore previous signal handlers and let them do
|
|
|
+ // their thing, so that the users can have the debugger break
|
|
|
+ // when a signal is raised, and so on.
|
|
|
+ restorePreviousSignalHandlers();
|
|
|
+ reportFatal(name);
|
|
|
+ raise(sig);
|
|
|
+}
|
|
|
|
|
|
- sa.sa_handler = handleSignal;
|
|
|
- sa.sa_flags = SA_ONSTACK;
|
|
|
- for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
|
|
|
- sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
|
|
|
- }
|
|
|
- }
|
|
|
+class FatalConditionHandler {
|
|
|
+ bool m_started;
|
|
|
|
|
|
- ~FatalConditionHandler() {
|
|
|
- reset();
|
|
|
- }
|
|
|
- static void reset() {
|
|
|
- if( isSet ) {
|
|
|
- // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
|
|
|
- for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
|
|
|
- sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
|
|
|
- }
|
|
|
- // Return the old stack
|
|
|
- sigaltstack(&oldSigStack, CATCH_NULL);
|
|
|
- isSet = false;
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
+ // Install/disengage implementation for specific platform.
|
|
|
+ // Should be if-defed to work on current platform, can assume
|
|
|
+ // engage-disengage 1:1 pairing.
|
|
|
+
|
|
|
+ void engage_platform() {
|
|
|
+ stack_t sigStack;
|
|
|
+ sigStack.ss_sp = altStackMem;
|
|
|
+ sigStack.ss_size = SIGSTKSZ;
|
|
|
+ sigStack.ss_flags = 0;
|
|
|
+ sigaltstack(&sigStack, &oldSigStack);
|
|
|
+ struct sigaction sa = {0};
|
|
|
+
|
|
|
+ sa.sa_handler = handleSignal;
|
|
|
+ sa.sa_flags = SA_ONSTACK;
|
|
|
+ for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
|
|
+ sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void disengage_platform() { restorePreviousSignalHandlers(); }
|
|
|
|
|
|
- bool FatalConditionHandler::isSet = false;
|
|
|
- struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
|
|
|
- stack_t FatalConditionHandler::oldSigStack = {};
|
|
|
- char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
|
|
|
+public:
|
|
|
+ FatalConditionHandler() : m_started(false) {
|
|
|
+ assert(!altStackMem &&
|
|
|
+ "Cannot initialize POSIX signal handler when one already exists");
|
|
|
+ if (altStackSize == 0) {
|
|
|
+ altStackSize = SIGSTKSZ;
|
|
|
+ }
|
|
|
+ altStackMem = new char[altStackSize]();
|
|
|
+ }
|
|
|
+
|
|
|
+ ~FatalConditionHandler() {
|
|
|
+ delete[] altStackMem;
|
|
|
+ // We signal that another instance can be constructed by zeroing
|
|
|
+ // out the pointer.
|
|
|
+ altStackMem = CATCH_NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ void engage() {
|
|
|
+ assert(!m_started && "Handler cannot be installed twice.");
|
|
|
+ m_started = true;
|
|
|
+ engage_platform();
|
|
|
+ }
|
|
|
+
|
|
|
+ void disengage() {
|
|
|
+ assert(m_started &&
|
|
|
+ "Handler cannot be uninstalled without being installed first");
|
|
|
+ m_started = false;
|
|
|
+ disengage_platform();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+#if defined(__GNUC__)
|
|
|
+#pragma GCC diagnostic pop
|
|
|
+#endif
|
|
|
|
|
|
} // namespace Catch
|
|
|
|
|
|
-# endif // CATCH_CONFIG_POSIX_SIGNALS
|
|
|
+#endif // CATCH_CONFIG_POSIX_SIGNALS
|
|
|
|
|
|
#endif // not Windows
|
|
|
|
|
|
+namespace Catch {
|
|
|
+
|
|
|
+//! Simple RAII guard for (dis)engaging the FatalConditionHandler
|
|
|
+class FatalConditionHandlerGuard {
|
|
|
+ FatalConditionHandler *m_handler;
|
|
|
+
|
|
|
+public:
|
|
|
+ FatalConditionHandlerGuard(FatalConditionHandler *handler)
|
|
|
+ : m_handler(handler) {
|
|
|
+ m_handler->engage();
|
|
|
+ }
|
|
|
+ ~FatalConditionHandlerGuard() { m_handler->disengage(); }
|
|
|
+};
|
|
|
+
|
|
|
+} // end namespace Catch
|
|
|
+
|
|
|
#include <cassert>
|
|
|
#include <set>
|
|
|
#include <string>
|
|
|
@@ -6938,9 +7075,8 @@ namespace Catch {
|
|
|
}
|
|
|
|
|
|
void invokeActiveTestCase() {
|
|
|
- FatalConditionHandler fatalConditionHandler; // Handle signals
|
|
|
+ FatalConditionHandlerGuard _(&m_fatalConditionhandler);
|
|
|
m_activeTestCase->invoke();
|
|
|
- fatalConditionHandler.reset();
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
@@ -6978,6 +7114,7 @@ namespace Catch {
|
|
|
std::vector<SectionEndInfo> m_unfinishedSections;
|
|
|
std::vector<ITracker*> m_activeSections;
|
|
|
TrackerContext m_trackerContext;
|
|
|
+ FatalConditionHandler m_fatalConditionhandler;
|
|
|
size_t m_prevPassed;
|
|
|
bool m_shouldReportUnexpected;
|
|
|
};
|