mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-25 23:06:10 +01:00
Fix disengage failure logs for FatalConditionHandlerGuard
FatalConditionHandlerGuard is used within RunContext::invokeActiveTestCase(). The intent of this guard is to avoid binary crash without failed test being reported. Still in case FatalConditionHandlerGuard destructor being called during stack unwinding AND finds unexpected top-level filter for SEH unhandled exception, the binary may still crash. As result of such crash the original exception details are being hidden. As the Catch2 provides only `CATCH_CATCH_ANON` macro, with no access to exception details by design, looks like the best way to handle issue is to: - state requirements explicitly by `noexcept` specifier - use `Catch::cerr()` to print out possible issue notification Signed-off-by: Kochetkov, Yuriy <yuriyx.kochetkov@intel.com>
This commit is contained in:
parent
7882f7359e
commit
2ce64d1d8f
@ -40,7 +40,7 @@ namespace Catch {
|
||||
// If neither SEH nor signal handling is required, the handler impls
|
||||
// do not have to do anything, and can be empty.
|
||||
void FatalConditionHandler::engage_platform() {}
|
||||
void FatalConditionHandler::disengage_platform() {}
|
||||
void FatalConditionHandler::disengage_platform() noexcept {}
|
||||
FatalConditionHandler::FatalConditionHandler() = default;
|
||||
FatalConditionHandler::~FatalConditionHandler() = default;
|
||||
|
||||
@ -124,9 +124,11 @@ namespace Catch {
|
||||
previousTopLevelExceptionFilter = SetUnhandledExceptionFilter(topLevelExceptionFilter);
|
||||
}
|
||||
|
||||
void FatalConditionHandler::disengage_platform() {
|
||||
void FatalConditionHandler::disengage_platform() noexcept {
|
||||
if (SetUnhandledExceptionFilter(previousTopLevelExceptionFilter) != topLevelExceptionFilter) {
|
||||
CATCH_RUNTIME_ERROR("Could not restore previous top level exception filter");
|
||||
Catch::cerr()
|
||||
<< "Unexpected SEH unhandled exception filter on disengage."
|
||||
<< " The filter was restored, but might be rolled back unexpectedly.";
|
||||
}
|
||||
previousTopLevelExceptionFilter = nullptr;
|
||||
}
|
||||
@ -168,7 +170,7 @@ namespace Catch {
|
||||
static stack_t oldSigStack{};
|
||||
static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};
|
||||
|
||||
static void restorePreviousSignalHandlers() {
|
||||
static void restorePreviousSignalHandlers() noexcept {
|
||||
// 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
|
||||
@ -231,7 +233,7 @@ namespace Catch {
|
||||
#endif
|
||||
|
||||
|
||||
void FatalConditionHandler::disengage_platform() {
|
||||
void FatalConditionHandler::disengage_platform() noexcept {
|
||||
restorePreviousSignalHandlers();
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace Catch {
|
||||
// Should be if-defed to work on current platform, can assume
|
||||
// engage-disengage 1:1 pairing.
|
||||
void engage_platform();
|
||||
void disengage_platform();
|
||||
void disengage_platform() noexcept;
|
||||
public:
|
||||
// Should also have platform-specific implementations as needed
|
||||
FatalConditionHandler();
|
||||
@ -44,7 +44,7 @@ namespace Catch {
|
||||
engage_platform();
|
||||
}
|
||||
|
||||
void disengage() {
|
||||
void disengage() noexcept {
|
||||
assert(m_started && "Handler cannot be uninstalled without being installed first");
|
||||
m_started = false;
|
||||
disengage_platform();
|
||||
|
Loading…
Reference in New Issue
Block a user