Skip to content

Commit

Permalink
Merge pull request #1831 from ApexAI/iox-1755-flush-testing-logger-on…
Browse files Browse the repository at this point in the history
…-terminate

iox-#1755 flush testing logger on terminate
  • Loading branch information
elBoberido authored Apr 18, 2023
2 parents e7b572b + 4523a08 commit 0cdf9ed
Showing 1 changed file with 50 additions and 4 deletions.
54 changes: 50 additions & 4 deletions iceoryx_hoofs/testing/testing_logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@

#include <iostream>

#include <csignal>
#include <cstdio>
#include <cstring>

// NOLINTNEXTLINE(hicpp-deprecated-headers) required to work on some platforms
#include <setjmp.h>

namespace iox
{
namespace testing
Expand Down Expand Up @@ -112,15 +119,54 @@ std::vector<std::string> TestingLogger::getLogMessages() noexcept
return logger.m_loggerData->buffer;
}

#if !defined(_WIN32)
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) global variable is required as jmp target
jmp_buf exitJmpBuffer;

static void sigHandler(int sig, siginfo_t*, void*)
{
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<TestingLogger&>(log::Logger::get()).printLogBuffer();

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&)
{
dynamic_cast<TestingLogger&>(log::Logger::get()).clearLogBuffer();
TestingLogger::setLogLevel(log::LogLevel::TRACE);

/// @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
std::set_terminate([]() {
std::cout << "Terminate called\n" << std::flush;
dynamic_cast<TestingLogger&>(log::Logger::get()).printLogBuffer();
std::abort();
});

#if !defined(_WIN32)
struct sigaction action = {};
memset(&action, 0, sizeof(struct sigaction));
sigemptyset(&action.sa_mask);

action.sa_flags = SA_NODEFER;
action.sa_sigaction = sigHandler;

sigaction(SIGSEGV, &action, nullptr);
sigaction(SIGFPE, &action, nullptr);
#endif
}

void LogPrinter::OnTestPartResult(const ::testing::TestPartResult& result)
Expand Down

0 comments on commit 0cdf9ed

Please sign in to comment.