From 2c859498d25e7ecb4b3ae866819380bcde3005ac Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Mon, 14 Nov 2022 14:41:21 +0100 Subject: [PATCH 1/4] iox-#1755 Flush TestingLogger on terminate --- iceoryx_hoofs/testing/testing_logger.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/iceoryx_hoofs/testing/testing_logger.cpp b/iceoryx_hoofs/testing/testing_logger.cpp index e2f751c968..40d01adb9b 100644 --- a/iceoryx_hoofs/testing/testing_logger.cpp +++ b/iceoryx_hoofs/testing/testing_logger.cpp @@ -117,6 +117,12 @@ void LogPrinter::OnTestStart(const ::testing::TestInfo&) dynamic_cast(log::Logger::get()).clearLogBuffer(); TestingLogger::setLogLevel(log::LogLevel::TRACE); + std::set_terminate([]() { + std::cout << "Terminate called\n" << std::flush; + dynamic_cast(log::Logger::get()).printLogBuffer(); + std::abort(); + }); + /// @todo iox-#1755 register signal handler for sigterm to flush to logger; /// there might be tests to register a handler itself and when this is /// done at each start of the test only the tests who use their From 5f7ec0437e884f0d47bfbec19561d70b683189b2 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Mon, 19 Dec 2022 20:09:21 +0100 Subject: [PATCH 2/4] iox-#1755 Flush TestingLogger on SIGSEGV --- iceoryx_hoofs/testing/testing_logger.cpp | 29 ++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/iceoryx_hoofs/testing/testing_logger.cpp b/iceoryx_hoofs/testing/testing_logger.cpp index 40d01adb9b..d8dc095fb6 100644 --- a/iceoryx_hoofs/testing/testing_logger.cpp +++ b/iceoryx_hoofs/testing/testing_logger.cpp @@ -19,6 +19,11 @@ #include +#include +#include +#include +#include + namespace iox { namespace testing @@ -112,6 +117,16 @@ std::vector TestingLogger::getLogMessages() noexcept return logger.m_loggerData->buffer; } +std::jmp_buf sigsevJmpPoint; + +static void sigsegvHandler(int /*sig*/, siginfo_t*, void*) +{ + std::cout << "SIGSEGV\n" << std::flush; + dynamic_cast(log::Logger::get()).printLogBuffer(); + + std::longjmp(&sigsevJmpPoint[0], 1); +} + void LogPrinter::OnTestStart(const ::testing::TestInfo&) { dynamic_cast(log::Logger::get()).clearLogBuffer(); @@ -123,10 +138,16 @@ void LogPrinter::OnTestStart(const ::testing::TestInfo&) std::abort(); }); - /// @todo iox-#1755 register signal handler for sigterm to flush to logger; - /// there might be tests to register a handler itself and when this is - /// done at each start of the test only the tests who use their - /// own signal handler are affected and don't get an log output on termination + struct sigaction action + { + }; + memset(&action, 0, sizeof(struct sigaction)); + sigemptyset(&action.sa_mask); + + action.sa_flags = SA_NODEFER; + action.sa_sigaction = sigsegvHandler; + + sigaction(SIGSEGV, &action, nullptr); } void LogPrinter::OnTestPartResult(const ::testing::TestPartResult& result) From 436db6565825655234e7840d97b4f15dd81bf4b4 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Mon, 3 Apr 2023 20:17:25 +0200 Subject: [PATCH 3/4] iox-#1755 Exclude Windows and catch SIGFPE --- iceoryx_hoofs/testing/testing_logger.cpp | 35 ++++++++++++++++++------ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/iceoryx_hoofs/testing/testing_logger.cpp b/iceoryx_hoofs/testing/testing_logger.cpp index d8dc095fb6..49d2a886c5 100644 --- a/iceoryx_hoofs/testing/testing_logger.cpp +++ b/iceoryx_hoofs/testing/testing_logger.cpp @@ -19,11 +19,13 @@ #include -#include #include #include #include +// NOLINTNEXTLINE(hicpp-deprecated-headers) required to work on some platforms +#include + namespace iox { namespace testing @@ -117,15 +119,31 @@ std::vector TestingLogger::getLogMessages() noexcept return logger.m_loggerData->buffer; } -std::jmp_buf sigsevJmpPoint; +#if !defined(_WIN32) +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) global variable is required as jmp target +jmp_buf exitJmpBuffer; -static void sigsegvHandler(int /*sig*/, siginfo_t*, void*) +static void sigsegvHandler(int sig, siginfo_t*, void*) { - std::cout << "SIGSEGV\n" << std::flush; + switch (sig) + { + case SIGSEGV: + std::cout << "SIGSEGV\n" << std::flush; + break; + case SIGFPE: + std::cout << "SIGFPE\n" << std::flush; + break; + default: + std::cout << "signal: " << sig << "\n" << std::flush; + break; + } dynamic_cast(log::Logger::get()).printLogBuffer(); - std::longjmp(&sigsevJmpPoint[0], 1); + constexpr int JMP_VALUE{1}; + // NOLINTNEXTLINE(cert-err52-cpp) exception cannot be used and longjmp/setjmp is a working fallback + longjmp(&exitJmpBuffer[0], JMP_VALUE); } +#endif void LogPrinter::OnTestStart(const ::testing::TestInfo&) { @@ -138,9 +156,8 @@ void LogPrinter::OnTestStart(const ::testing::TestInfo&) std::abort(); }); - struct sigaction action - { - }; +#if !defined(_WIN32) + struct sigaction action = {}; memset(&action, 0, sizeof(struct sigaction)); sigemptyset(&action.sa_mask); @@ -148,6 +165,8 @@ void LogPrinter::OnTestStart(const ::testing::TestInfo&) action.sa_sigaction = sigsegvHandler; sigaction(SIGSEGV, &action, nullptr); + sigaction(SIGFPE, &action, nullptr); +#endif } void LogPrinter::OnTestPartResult(const ::testing::TestPartResult& result) From 4523a08c6c0a778cb354bbecd1003fe55e66147b Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Thu, 13 Apr 2023 14:46:04 +0200 Subject: [PATCH 4/4] iox-#1755 Rename sigHandler function --- iceoryx_hoofs/testing/testing_logger.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iceoryx_hoofs/testing/testing_logger.cpp b/iceoryx_hoofs/testing/testing_logger.cpp index 49d2a886c5..357f6ec71f 100644 --- a/iceoryx_hoofs/testing/testing_logger.cpp +++ b/iceoryx_hoofs/testing/testing_logger.cpp @@ -123,7 +123,7 @@ std::vector TestingLogger::getLogMessages() noexcept // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) global variable is required as jmp target jmp_buf exitJmpBuffer; -static void sigsegvHandler(int sig, siginfo_t*, void*) +static void sigHandler(int sig, siginfo_t*, void*) { switch (sig) { @@ -162,7 +162,7 @@ void LogPrinter::OnTestStart(const ::testing::TestInfo&) sigemptyset(&action.sa_mask); action.sa_flags = SA_NODEFER; - action.sa_sigaction = sigsegvHandler; + action.sa_sigaction = sigHandler; sigaction(SIGSEGV, &action, nullptr); sigaction(SIGFPE, &action, nullptr);