/* * Copyright (C) 2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/test/common/libult/signal_utils.h" #include "gtest/gtest.h" #include #include std::string lastTest(""); namespace NEO { extern const unsigned int ultIterationMaxTime; 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 currentUltIterationMaxTime = NEO::ultIterationMaxTime; auto ultIterationMaxTimeEnv = getenv("NEO_ULT_ITERATION_MAX_TIME"); if (ultIterationMaxTimeEnv != nullptr) { currentUltIterationMaxTime = atoi(ultIterationMaxTimeEnv); } unsigned int alarmTime = currentUltIterationMaxTime * ::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 << 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; }