53 log(
Debug(),
"Registering uHAL SIGBUS handler");
55 sigemptyset(&mAction.sa_mask);
56 if (sigaction(SIGBUS, &mAction, &mOriginalAction) != 0) {
57 exception::SignalHandlerNotRegistered lExc;
58 log(lExc,
"Failed to register SIGBUS handler (in SigBusGuard constructor); errno=",
Integer(errno),
", meaning ",
Quote (strerror(errno)));
63 sigset_t lMaskedSignals;
64 sigfillset(&lMaskedSignals);
65 sigdelset(&lMaskedSignals, SIGKILL);
66 sigdelset(&lMaskedSignals, SIGSTOP);
67 sigdelset(&lMaskedSignals, SIGINT);
68 sigdelset(&lMaskedSignals, SIGBUS);
69 const int lErrNo = pthread_sigmask(SIG_SETMASK, &lMaskedSignals, &mOriginalMask);
71 exception::SignalMaskingFailure lExc;
72 log(lExc,
"Failed to update signal mask in SigBusGuard constructor; errno=",
Integer(lErrNo),
", meaning ",
Quote (strerror(lErrNo)));
75 if (sigismember(&mOriginalMask, SIGBUS) != 1) {
76 exception::SignalNotBlocked lExc;
77 log(lExc,
"SIGBUS must be blocked (by all threads) before using SigBusGuard");
87 log(
Error(),
"Failed to re-register old SIGBUS handler (in SigBusGuard destructor); errno=",
Integer(errno),
", meaning ",
Quote (strerror(errno)));
89 log(
Debug(),
"Restored original SIGBUS handler");
92 const int lErrNo = pthread_sigmask(SIG_SETMASK, &
mOriginalMask, NULL);
94 log(
Error(),
"Failed to update signal mask in SigBusGuard constructor; errno=",
Integer(lErrNo),
", meaning ",
Quote (strerror(lErrNo)));
107 if (SIGBUS == sigsetjmp(
sEnv,1)) {
110 exception::SigBusError lException;
111 log (lException, aMessage);
124 sigemptyset(&lSigSet);
125 sigaddset(&lSigSet, SIGBUS);
126 const int lErrNo = pthread_sigmask(SIG_BLOCK, &lSigSet, NULL);
128 exception::SignalMaskingFailure lExc;
129 log(lExc,
"Failed to update signal mask; errno=",
Integer(lErrNo),
", meaning ",
Quote (strerror(lErrNo)));
140 char message[] =
"WARNING: A uHAL SigBusGuard has been constructed but SIGBUS was received outside of the 'protect' method. This will cause *undefined behaviour*.\nAfter creating a uhal::SigBusGuard instance, you must run any code that can raise SIGBUS inside the SigBusGuard::protect method (using its std::function argument).\n";
145 if (aSignal == SIGBUS)
146 siglongjmp(
sEnv, aSignal);
void protect(const std::function< void()> &, const std::string &)
struct sigaction mOriginalAction
static void blockSIGBUS()
static volatile sig_atomic_t sProtected
_Quote< T > Quote(const T &aT)
_Integer< T, IntFmt<> > Integer(const T &aT)
Forward declare a function which creates an instance of the ultra-lightweight wrapper from an integer...
void log(FatalLevel &aFatal, const T0 &aArg0)
Function to add a log entry at Fatal level.