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
|
/*
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/abort.h"
#include "shared/source/helpers/non_copyable_or_moveable.h"
#include <cstdio>
#include <cstdlib>
#include <execinfo.h>
#include <setjmp.h>
#include <signal.h>
static jmp_buf jmpbuf;
class SafetyGuardLinux : NEO::NonCopyableAndNonMovableClass {
public:
SafetyGuardLinux() {
struct sigaction sigact {};
sigact.sa_sigaction = sigAction;
sigact.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction(SIGSEGV, &sigact, &previousSigSegvAction);
sigaction(SIGILL, &sigact, &previousSigIllvAction);
}
~SafetyGuardLinux() {
if (previousSigSegvAction.sa_sigaction) {
sigaction(SIGSEGV, &previousSigSegvAction, NULL);
}
if (previousSigIllvAction.sa_sigaction) {
sigaction(SIGILL, &previousSigIllvAction, NULL);
}
}
static void sigAction(int sigNum, siginfo_t *info, void *ucontext) {
const int callstackDepth = 30;
void *addresses[callstackDepth];
char **callstack;
int backtraceSize = 0;
backtraceSize = backtrace(addresses, callstackDepth);
callstack = backtrace_symbols(addresses, backtraceSize);
for (int i = 0; i < backtraceSize; ++i) {
printf("[%d]: %s\n", i, callstack[i]);
}
free(callstack);
longjmp(jmpbuf, 1);
}
template <typename T, typename Object, typename Method>
T call(Object *object, Method method, T retValueOnCrash) {
int jump = 0;
jump = setjmp(jmpbuf);
if (jump == 0) {
return (object->*method)();
} else {
if (onSigSegv) {
onSigSegv();
} else {
NEO::abortExecution();
}
}
return retValueOnCrash;
}
typedef void (*callbackFunction)();
callbackFunction onSigSegv = nullptr;
struct sigaction previousSigSegvAction {};
struct sigaction previousSigIllvAction {};
};
static_assert(NEO::NonCopyableAndNonMovable<SafetyGuardLinux>);
|