142 lines
4.3 KiB
C++
142 lines
4.3 KiB
C++
/*
|
|
* Copyright (C) 2022-2024 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
*/
|
|
|
|
#include "shared/test/common/libult/signal_utils.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
|
|
std::string lastTest("");
|
|
|
|
namespace NEO {
|
|
extern const unsigned int ultIterationMaxTimeInS;
|
|
extern const char *executionName;
|
|
} // namespace NEO
|
|
|
|
int newStdOut = -1;
|
|
|
|
struct sigaction oldSigAbrt;
|
|
void handleSIGABRT(int signal) {
|
|
if (newStdOut != -1) {
|
|
dup2(newStdOut, 1);
|
|
}
|
|
std::cout << "SIGABRT in " << NEO::executionName << ", on: " << lastTest << std::endl;
|
|
if (sigaction(SIGABRT, &oldSigAbrt, nullptr) == -1) {
|
|
std::cout << "FATAL: cannot fatal SIGABRT handler" << std::endl;
|
|
std::cout << "FATAL: try SEGV" << std::endl;
|
|
uint8_t *ptr = nullptr;
|
|
*ptr = 0;
|
|
std::cout << "FATAL: still alive, call exit()" << std::endl;
|
|
exit(-1);
|
|
}
|
|
raise(signal);
|
|
}
|
|
|
|
struct timespec startTimeSpec = {};
|
|
struct timespec alrmTimeSpec = {};
|
|
void handleSIGALRM(int signal) {
|
|
if (newStdOut != -1) {
|
|
dup2(newStdOut, 1);
|
|
}
|
|
std::cout << "Tests timeout in " << NEO::executionName << ", ";
|
|
if (clock_gettime(CLOCK_MONOTONIC_RAW, &alrmTimeSpec) == 0) {
|
|
auto deltaSec = alrmTimeSpec.tv_sec - startTimeSpec.tv_sec;
|
|
std::cout << " after: " << deltaSec << " seconds";
|
|
}
|
|
std::cout << " on: " << lastTest << std::endl;
|
|
abort();
|
|
}
|
|
|
|
void handleSIGSEGV(int signal) {
|
|
if (newStdOut != -1) {
|
|
dup2(newStdOut, 1);
|
|
}
|
|
std::cout << "SIGSEGV in " << NEO::executionName << ", on: " << lastTest << std::endl;
|
|
abort();
|
|
}
|
|
|
|
int setAbrt(bool enableAbrt) {
|
|
std::cout << "enable SIGABRT handler: " << enableAbrt << std::endl;
|
|
struct sigaction sa;
|
|
sa.sa_handler = &handleSIGABRT;
|
|
sa.sa_flags = SA_RESTART;
|
|
sigfillset(&sa.sa_mask);
|
|
if (sigaction(SIGABRT, &sa, &oldSigAbrt) == -1) {
|
|
std::cout << "FATAL ERROR: cannot intercept SIGABRT" << std::endl;
|
|
return -2;
|
|
}
|
|
if (newStdOut == -1) {
|
|
newStdOut = dup(1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int setAlarm(bool enableAlarm) {
|
|
std::cout << "enable SIGALRM handler: " << enableAlarm << std::endl;
|
|
if (enableAlarm) {
|
|
std::string envVar = std::string("NEO_") + NEO::executionName + "_DISABLE_TEST_ALARM";
|
|
char *envValue = getenv(envVar.c_str());
|
|
if (envValue != nullptr) {
|
|
enableAlarm = false;
|
|
std::cout << "WARNING: SIGALRM handler disabled by environment variable: " << envVar << std::endl;
|
|
}
|
|
}
|
|
if (enableAlarm) {
|
|
if (clock_gettime(CLOCK_MONOTONIC_RAW, &startTimeSpec)) {
|
|
startTimeSpec.tv_sec = 0;
|
|
}
|
|
|
|
auto currentUltIterationMaxTimeInS = NEO::ultIterationMaxTimeInS;
|
|
std::string envVar = std::string("NEO_") + NEO::executionName + "_ITERATION_MAX_TIME";
|
|
auto ultIterationMaxTimeInSEnv = getenv(envVar.c_str());
|
|
if (ultIterationMaxTimeInSEnv != nullptr) {
|
|
currentUltIterationMaxTimeInS = atoi(ultIterationMaxTimeInSEnv);
|
|
} else {
|
|
ultIterationMaxTimeInSEnv = getenv("NEO_ULT_ITERATION_MAX_TIME");
|
|
if (ultIterationMaxTimeInSEnv != nullptr) {
|
|
currentUltIterationMaxTimeInS = atoi(ultIterationMaxTimeInSEnv);
|
|
}
|
|
}
|
|
unsigned int alarmTime = currentUltIterationMaxTimeInS * ::testing::GTEST_FLAG(repeat);
|
|
|
|
struct sigaction sa;
|
|
sa.sa_handler = &handleSIGALRM;
|
|
sa.sa_flags = SA_RESTART;
|
|
sigfillset(&sa.sa_mask);
|
|
if (sigaction(SIGALRM, &sa, NULL) == -1) {
|
|
std::cout << "FATAL ERROR: cannot intercept SIGALRM" << std::endl;
|
|
return -2;
|
|
}
|
|
if (newStdOut == -1) {
|
|
newStdOut = dup(1);
|
|
}
|
|
alarm(alarmTime);
|
|
std::cout << "set timeout to: " << alarmTime << " seconds" << std::endl;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int setSegv(bool enableSegv) {
|
|
std::cout << "enable SIGSEGV handler: " << enableSegv << std::endl;
|
|
struct sigaction sa;
|
|
sa.sa_handler = &handleSIGSEGV;
|
|
sa.sa_flags = SA_RESTART;
|
|
sigfillset(&sa.sa_mask);
|
|
if (sigaction(SIGSEGV, &sa, NULL) == -1) {
|
|
std::cout << "FATAL ERROR: cannot intercept SIGSEGV" << std::endl;
|
|
return -2;
|
|
}
|
|
if (newStdOut == -1) {
|
|
newStdOut = dup(1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void cleanupSignals() {}
|