Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2
diff options
context:
space:
mode:
authorDuncan Horn2025-09-27 02:09:34 -0700
committerGitHub2025-09-27 11:09:34 +0200
commit0e772cc0d29e7518f84a1ad11aa179167a6ab6bc (patch)
treec5e707777ac07e5ff607395449f68092cc380da1 /src/catch2
parent3bcd0a4e74b2bb5f6ec80ad464775442af84343c (diff)
downloadcatch3-0e772cc0d29e7518f84a1ad11aa179167a6ab6bc.tar.gz
Allow composability of unhandled exception filters (#3033)
The change is very simple. If a handler previously existed, Catch2 will invoke it after printing out its output. I've also updated the comment to better reflect that it's returning EXCEPTION_CONTINUE_SEARCH even in scenarios where the exception is one that the library cares about.
Diffstat (limited to 'src/catch2')
-rw-r--r--src/catch2/internal/catch_fatal_condition_handler.cpp18
1 files changed, 11 insertions, 7 deletions
diff --git a/src/catch2/internal/catch_fatal_condition_handler.cpp b/src/catch2/internal/catch_fatal_condition_handler.cpp
index 26f894d6..3dfa1383 100644
--- a/src/catch2/internal/catch_fatal_condition_handler.cpp
+++ b/src/catch2/internal/catch_fatal_condition_handler.cpp
@@ -86,23 +86,27 @@ namespace Catch {
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
};
+ // Since we do not support multiple instantiations, we put these
+ // into global variables and rely on cleaning them up in outlined
+ // constructors/destructors
+ static LPTOP_LEVEL_EXCEPTION_FILTER previousTopLevelExceptionFilter = nullptr;
+
+
static LONG CALLBACK topLevelExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) {
for (auto const& def : signalDefs) {
if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
reportFatal(def.name);
}
}
- // If its not an exception we care about, pass it along.
+ // If a filter was previously registered, invoke it
+ if (previousTopLevelExceptionFilter) {
+ return previousTopLevelExceptionFilter(ExceptionInfo);
+ }
+ // Otherwise, pass along all exceptions.
// 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 LPTOP_LEVEL_EXCEPTION_FILTER previousTopLevelExceptionFilter = nullptr;
-
-
// For MSVC, we reserve part of the stack memory for handling
// memory overflow structured exception.
FatalConditionHandler::FatalConditionHandler() {