1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/*
* Copyright (C) 2022-2025 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;
extern const char *apiName;
} // namespace NEO
int newStdOut = -1;
struct sigaction oldSigAbrt;
void handleSIGABRT(int signal) {
if (newStdOut != -1) {
dup2(newStdOut, 1);
}
std::cout << "SIGABRT in " << NEO::apiName << " " << 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 = {};
auto currentUltIterationMaxTimeInS = NEO::ultIterationMaxTimeInS;
void handleSIGALRM(int signal) {
if (newStdOut != -1) {
dup2(newStdOut, 1);
}
uint32_t elapsedTime = currentUltIterationMaxTimeInS;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &alrmTimeSpec) == 0) {
elapsedTime = static_cast<uint32_t>(alrmTimeSpec.tv_sec - startTimeSpec.tv_sec);
}
handleTestsTimeout(lastTest, elapsedTime);
}
void handleSIGSEGV(int signal) {
if (newStdOut != -1) {
dup2(newStdOut, 1);
}
std::cout << "SIGSEGV in " << NEO::apiName << " " << 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;
}
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() {}
|