ATLAS Offline Software
Loading...
Searching...
No Matches
Athena::Signal Class Reference

Utilities for handling signals and fatal errors. More...

#include <SealSignal.h>

Collaboration diagram for Athena::Signal:

Public Types

typedef bool(* QuitHook) (int sig, siginfo_t *info, void *x)
 Application clean-up hook invoked before #quit(int , siginfo_t *, void *) exits from program termination signals (SIGHUP, SIGTERM or SIGQUIT).
typedef bool(* FatalHook) (int sig, siginfo_t *info, void *x)
 Application hook to run in fatal().
typedef void(* FatalReturn) (int sig, siginfo_t *info, void *x)
 Application hook to jump back to the main program from a fatal signal, for example using #siglongjmp.
typedef void(* HandlerType) (int sig, siginfo_t *info, void *extra)
 Signal handler type.

Static Public Member Functions

static const char * name (int sig)
 Return the name of the signal number sig.
static HandlerType handler (int sig, sigset_t *mask=0)
 Return the current handler for signal number sig and its blocked signals in mask (if non-null).
static HandlerType handle (int sig, HandlerType handler, const sigset_t *blockMask=0)
 Install a new signal handler handler for signal number sig and returns the old handler.
static void revert (int sig)
 Revert the signal number sig back to its default behaviour.
static void ignore (int sig)
 Ignore the signal number sig.
static void block (int sig, bool sense)
 Block or unblock the signal number sig.
static void block (const sigset_t *mask, bool sense)
 Block or unblock the signals specified by mask.
static void mask (const sigset_t *mask, sigset_t *old=0)
 Set the list of currently blocked signals to mask and return the old setting in old (if non-null).
static int raise (int sig)
 Raise the signal number sig.
static int kill (pid_t process, int sig)
 Send the signal sig to process identified by process.
static int queue (int sig, int value=0)
 Queue signal sig for this process with additional data value.
static int queue (int sig, void *value)
 Queue signal sig for this process with additional data value.
static int queue (pid_t process, int sig, int value=0)
 Queue signal sig with additional data value for process.
static int queue (pid_t process, int sig, void *value)
 Queue signal sig with additional data value for process.
static bool pending (int sig)
 Check if sig is pending for this process.
static void pending (sigset_t *mask)
 Return in mask the list of signals pending for this process.
static void suspend (const sigset_t *mask)
 Temporarily replace the signal mask of the process with mask and then suspend until a signal is received.
static bool wait (int sig, siginfo_t *info=0, long msecs=-1)
 Suspend the thread waiting for signal sig at most msecs milliseconds.
static int wait (const sigset_t *mask, siginfo_t *info=0, long msecs=-1)
 Suspend the thread waiting for signals specified by mask for at most msecs milliseconds.
static void handleQuit ATLAS_NOT_THREAD_SAFE (QuitHook hook=0)
static QuitHook handleQuitHook ATLAS_NOT_THREAD_SAFE (void)
static void quit ATLAS_NOT_THREAD_SAFE (int sig, siginfo_t *info, void *x)
static void handleFatal ATLAS_NOT_THREAD_SAFE (const char *applicationName=0, IOFD fd=IOFD_INVALID, FatalHook hook=0, FatalReturn mainreturn=0, unsigned options=FATAL_DEFAULT)
static IOFD handleFatalFd ATLAS_NOT_THREAD_SAFE (void)
static FatalHook handleFatalHook ATLAS_NOT_THREAD_SAFE (void)
static FatalReturn handleFatalReturn ATLAS_NOT_THREAD_SAFE (void)
static unsigned handleFatalOptions ATLAS_NOT_THREAD_SAFE (void)
static void fatal ATLAS_NOT_THREAD_SAFE (int sig, siginfo_t *info, void *x)
static bool fatalDump ATLAS_NOT_THREAD_SAFE (int sig, siginfo_t *info, void *x, IOFD fd, unsigned options)
static bool fatalDump ATLAS_NOT_THREAD_SAFE (int sig, siginfo_t *info, void *x)
static int fatalLevel ATLAS_NOT_THREAD_SAFE (void)
static bool crashed ATLAS_NOT_THREAD_SAFE (void)
static void dumpInfo (IOFD fd, char *buf, unsigned int buf_size, int sig, const siginfo_t *info)
 Utility function to dump the signal info descriptor for signal sig, as obtained for instance through signal handler parameters or wait().
static void dumpMemory (IOFD fd, char *buf, unsigned int buf_size, const void *data, size_t n)
 Utility function to dump memory section from data for n bytes.
static unsigned long dumpContext (IOFD fd, char *buf, unsigned int buf_size, const void *context)
 Utility function to dump the process context, as obtained for instance through signal handler parameters, unix getcontext() or Windows GetThreadContext().
static const char * describe (int sig, int code)
 Return the description for signal info code code for signal number sig.

Static Public Attributes

static const int USR1_DUMP_CORE = 1
 Option that instructs #fatal(int, siginfo_t *, void *) to call #coredump() on SIGUSR1.
static const int FATAL_ON_QUIT = 2
 Option to make SIGHUP, SIGTERM and SIGQUIT fatal instead of just #quit(int , siginfo_t *, void *) signals.
static const int FATAL_ON_INT = 4
 Option to make SIGINT fatal.
static const int FATAL_DUMP_CORE = 8
 Option to make #fatal(int, siginfo_t *, void *) dump a core file before crashing.
static const int FATAL_DUMP_SIG = 16
 Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *, void *)) to dump the signal name (as reported by name()).
static const int FATAL_DUMP_STACK = 32
 Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *, void *)) to dump stack backtrace for the offending code location.
static const int FATAL_DUMP_LIBS = 64
 Option to make #fataldump(int sig, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *, void *)) to dump the list of currently loaded shared libraries.
static const int FATAL_DUMP_CONTEXT = 128
 Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *, void *)) to dump the machine context (registers etc.) from the fault position.
static const int FATAL_AUTO_EXIT = 256
 Option to make #fatal(int, siginfo_t *, void *) exit via #quit(int , siginfo_t *, void *).
static const int FATAL_DEFAULT
 Default options to #handleFatal(const char *, IOFD fd, FatalHook, FatalReturn, unsigned.

Static Private Member Functions

static void trampoline (int sig)
 Internal signal handler trampoline to convert handler arguments to look more like POSIX signals.

Static Private Attributes

static bool s_crashed = false
 Indicator that the application has been crashed: that a fatal signal has been delivered.
static int s_inFatal = 0
 Indicator that we are currently executing inside #fatal().
static std::atomic< unsigned long > s_lastSP
 Used to switch to a raw stack dump if we crash during a backtrace.
static const char * s_applicationName = 0
 The current application name.
static IOFD s_fatalFd = IOFD_INVALID
 The output file descriptor for #fataldump().
static FatalHook s_fatalHook = 0
 The application handler hook for fatal signals.
static FatalReturn s_fatalReturn = 0
 The application main return hook for fatal signals.
static unsigned s_fatalOptions = 0
 The current fatal signal handling options.
static QuitHook s_quitHook = 0
 The application handler hook for quitting-related signals.
static HandlerType s_trampolines [NSIG]
 Actual signal handlers when POSIX signals are not available.

Detailed Description

Utilities for handling signals and fatal errors.

FIXME: POSIX single-threaded vs. multi-threaded signals?

  • all threads should block all the signals
  • one thread should do sigwait.

The fatal error handling is largely inspired by code in DDD, the Data Display Debugger, and by the examples in GNU libc manual.

Definition at line 100 of file SealSignal.h.

Member Typedef Documentation

◆ FatalHook

typedef bool(* Athena::Signal::FatalHook) (int sig, siginfo_t *info, void *x)

Application hook to run in fatal().

The hook should return true if the signal handler should proceed to die. sig is the signal number, or its negative if core was dumped and, as far as can determined, successfully produced.

The fatal hooks should, if possible, perform clean-ups similar to QuitHook. The application may achieve this by actually using the quit by setting FATAL_AUTO_EXIT for #handleFatal(const char *, IOFD fd, FatalHook, FatalReturn, unsigned), or it could reuse an internal function in both handlers.

Definition at line 176 of file SealSignal.h.

◆ FatalReturn

typedef void(* Athena::Signal::FatalReturn) (int sig, siginfo_t *info, void *x)

Application hook to jump back to the main program from a fatal signal, for example using #siglongjmp.

It must never return. sig is the signal number, or its negative if core was dumped and, as far as can determined, successfully produced.

Definition at line 182 of file SealSignal.h.

◆ HandlerType

typedef void(* Athena::Signal::HandlerType) (int sig, siginfo_t *info, void *extra)

Signal handler type.

This is defined explicitly and does not necessarily match the system's concept of signal handler type. If necessary, suitable trampolines are used internally to make sure the arguments make sense.

Parameters
sigThe signal number.
infoPointer to signal info. This pointer will be null on platforms that do not support POSIX signals.
extraExtra argument, e.g. the fault address. This pointer will be null on platforms that do not support POSIX signals.

Definition at line 196 of file SealSignal.h.

◆ QuitHook

typedef bool(* Athena::Signal::QuitHook) (int sig, siginfo_t *info, void *x)

Application clean-up hook invoked before #quit(int , siginfo_t *, void *) exits from program termination signals (SIGHUP, SIGTERM or SIGQUIT).

The handler should return true if the signal handler should proceed to exit the application. Note that certain options to #handlFatal() cause this hook to be invoked for fatal signals. If such behaviour is enabled, be sure to check the #crashed() status before deciding to let the application to continue.

The quit hook should take care of resetting terminal modes, killing child processes, removing lock files, and so forth.

Definition at line 165 of file SealSignal.h.

Member Function Documentation

◆ ATLAS_NOT_THREAD_SAFE() [1/13]

void handleFatal Athena::Signal::ATLAS_NOT_THREAD_SAFE ( const char * applicationName = 0,
IOFD fd = IOFD_INVALID,
FatalHook hook = 0,
FatalReturn mainreturn = 0,
unsigned options = FATAL_DEFAULT )
static

◆ ATLAS_NOT_THREAD_SAFE() [2/13]

bool fatalDump Athena::Signal::ATLAS_NOT_THREAD_SAFE ( int sig,
siginfo_t * info,
void * x )
static

◆ ATLAS_NOT_THREAD_SAFE() [3/13]

void fatal Athena::Signal::ATLAS_NOT_THREAD_SAFE ( int sig,
siginfo_t * info,
void * x )
static

◆ ATLAS_NOT_THREAD_SAFE() [4/13]

void quit Athena::Signal::ATLAS_NOT_THREAD_SAFE ( int sig,
siginfo_t * info,
void * x )
static

◆ ATLAS_NOT_THREAD_SAFE() [5/13]

bool fatalDump Athena::Signal::ATLAS_NOT_THREAD_SAFE ( int sig,
siginfo_t * info,
void * x,
IOFD fd,
unsigned options )
static

◆ ATLAS_NOT_THREAD_SAFE() [6/13]

void handleQuit Athena::Signal::ATLAS_NOT_THREAD_SAFE ( QuitHook hook = 0)
static

◆ ATLAS_NOT_THREAD_SAFE() [7/13]

bool crashed Athena::Signal::ATLAS_NOT_THREAD_SAFE ( void )
static

◆ ATLAS_NOT_THREAD_SAFE() [8/13]

int fatalLevel Athena::Signal::ATLAS_NOT_THREAD_SAFE ( void )
static

◆ ATLAS_NOT_THREAD_SAFE() [9/13]

unsigned handleFatalOptions Athena::Signal::ATLAS_NOT_THREAD_SAFE ( void )
static

◆ ATLAS_NOT_THREAD_SAFE() [10/13]

FatalReturn handleFatalReturn Athena::Signal::ATLAS_NOT_THREAD_SAFE ( void )
static

◆ ATLAS_NOT_THREAD_SAFE() [11/13]

FatalHook handleFatalHook Athena::Signal::ATLAS_NOT_THREAD_SAFE ( void )
static

◆ ATLAS_NOT_THREAD_SAFE() [12/13]

IOFD handleFatalFd Athena::Signal::ATLAS_NOT_THREAD_SAFE ( void )
static

◆ ATLAS_NOT_THREAD_SAFE() [13/13]

QuitHook handleQuitHook Athena::Signal::ATLAS_NOT_THREAD_SAFE ( void )
static

◆ block() [1/2]

void Athena::Signal::block ( const sigset_t * mask,
bool sense )
static

Block or unblock the signals specified by mask.

The signals are blocked if sense is true, unblocked otherwise. This function is implemented only on systems with POSIX signals.

Definition at line 352 of file SealSignal.cxx.

353{
354#if HAVE_POSIX_SIGNALS
355 // FIXME: threads -- need to use pthread_sigmask
356 sigprocmask (sense ? SIG_BLOCK : SIG_UNBLOCK, mask, 0);
357#endif
358}
static void mask(const sigset_t *mask, sigset_t *old=0)
Set the list of currently blocked signals to mask and return the old setting in old (if non-null).

◆ block() [2/2]

void Athena::Signal::block ( int sig,
bool sense )
static

Block or unblock the signal number sig.

The signal is blocked if sense is true, unblocked otherwise. This function is implemented only on systems with POSIX signals.

Definition at line 337 of file SealSignal.cxx.

338{
339#if HAVE_POSIX_SIGNALS
340 // FIXME: threads -- need to use pthread_sigmask
342 sigemptyset (&mask);
343 sigaddset (&mask, sig);
344 block (&mask, sense);
345#endif
346}
#define sigemptyset(x)
Definition SealSignal.h:82
#define sigaddset(x, y)
Definition SealSignal.h:84
int sigset_t
Definition SealSignal.h:80
static void block(int sig, bool sense)
Block or unblock the signal number sig.

◆ describe()

const char * Athena::Signal::describe ( int sig,
int code )
static

Return the description for signal info code code for signal number sig.

The code should come from siginfo_t::si_code.

Definition at line 967 of file SealSignal.cxx.

968{
969 static const struct { int sig; int code; const char *desc; } infos [] = {
970#if HAVE_POSIX_SIGNALS
971 { -1, SI_USER, "user sent: kill, sigsend or raise" },
972# ifdef SI_KERNEL
973 { -1, SI_KERNEL, "kernel" },
974# endif
975 { -1, SI_QUEUE, "sigqueue" },
976 { -1, SI_TIMER, "timer expired" },
977 { -1, SI_MESGQ, "mesq state changed" },
978 { -1, SI_ASYNCIO, "AIO completed" },
979# ifdef SI_SIGIO // not solaris
980 { -1, SI_SIGIO, "queued SIGIO" },
981# endif
982
983# ifdef ILL_NOOP // darwin
984 { SIGILL, ILL_NOOP, "noop" },
985# endif
986 { SIGILL, ILL_ILLOPC, "illegal opcode" },
987# ifdef ILL_ILLOPN // not darwin
988 { SIGILL, ILL_ILLOPN, "illegal operand" },
989# endif
990# ifdef ILL_ILLADR // not darwin
991 { SIGILL, ILL_ILLADR, "illegal addressing mode" },
992# endif
993 { SIGILL, ILL_ILLTRP, "illegal trap" },
994 { SIGILL, ILL_PRVOPC, "privileged opcode" },
995# ifdef ILL_PRVREG // not darwin
996 { SIGILL, ILL_PRVREG, "privileged register" },
997# endif
998# ifdef ILL_COPROC // not darwin
999 { SIGILL, ILL_COPROC, "coprocessor error" },
1000# endif
1001# ifdef ILL_BADSTK // not darwin
1002 { SIGILL, ILL_BADSTK, "internal stack error" },
1003# endif
1004
1005# ifdef FPE_NOOP // darwin
1006 { SIGFPE, FPE_NOOP, "noop" },
1007# endif
1008# ifdef FPE_INTDIV // not darwin
1009 { SIGFPE, FPE_INTDIV, "integer divide by zero" },
1010# endif
1011# ifdef FPE_INTOVF // not darwin
1012 { SIGFPE, FPE_INTOVF, "integer overflow" },
1013# endif
1014 { SIGFPE, FPE_FLTDIV, "floating point divide by zero" },
1015 { SIGFPE, FPE_FLTOVF, "floating point overflow" },
1016 { SIGFPE, FPE_FLTUND, "floating point underflow" },
1017 { SIGFPE, FPE_FLTRES, "floating point inexact result" },
1018 { SIGFPE, FPE_FLTINV, "floating point invalid operation" },
1019# ifdef FPE_FLTSUB // not darwin
1020 { SIGFPE, FPE_FLTSUB, "subscript out of range" },
1021# endif
1022
1023# ifdef SEGV_NOOP // darwin
1024 { SIGSEGV, SEGV_NOOP, "noop" },
1025# endif
1026 { SIGSEGV, SEGV_MAPERR, "address not mapped to object" },
1027 { SIGSEGV, SEGV_ACCERR, "invalid permissions for mapped object" },
1028
1029# ifdef BUS_NOOP // darwin
1030 { SIGBUS, BUS_NOOP, "noop" },
1031# endif
1032 { SIGBUS, BUS_ADRALN, "invalid address alignment" },
1033# ifdef BUS_ADRERR // not darwin
1034 { SIGBUS, BUS_ADRERR, "non-existent physical address" },
1035# endif
1036# ifdef BUS_OBJERR // not darwin
1037 { SIGBUS, BUS_OBJERR, "object specific hardware error" },
1038# endif
1039
1040# ifdef TRAP_BRKPT // not darwin
1041 { SIGTRAP, TRAP_BRKPT, "process break point" },
1042# endif
1043# ifdef TRAP_TRACE // not darwin
1044 { SIGTRAP, TRAP_TRACE, "process trace trap" },
1045# endif
1046
1047# ifdef CLD_NOOP // darwin
1048 { SIGCHLD, CLD_NOOP, "noop" },
1049# endif
1050 { SIGCHLD, CLD_EXITED, "child has exited" },
1051 { SIGCHLD, CLD_KILLED, "child was killed" },
1052 { SIGCHLD, CLD_DUMPED, "child terminated abnormally" },
1053 { SIGCHLD, CLD_TRAPPED, "traced child has trapped" },
1054 { SIGCHLD, CLD_STOPPED, "child has stopped" },
1055 { SIGCHLD, CLD_CONTINUED,"stopped child has continued" },
1056
1057# ifdef SIGPOLL // not darwin
1058 { SIGPOLL, POLL_IN, "data input available" },
1059 { SIGPOLL, POLL_OUT, "output buffers available" },
1060 { SIGPOLL, POLL_MSG, "input message available" },
1061 { SIGPOLL, POLL_ERR, "i/o error" },
1062 { SIGPOLL, POLL_PRI, "high priority input available" },
1063 { SIGPOLL, POLL_HUP, "device disconnected" },
1064# endif
1065#endif // HAVE_POSIX_SIGNALS
1066
1067 { -1, -1, 0 }
1068 };
1069
1070 for (unsigned i = 0; infos [i].desc; ++i)
1071 if ((infos [i].sig == -1 || infos [i].sig == sig)
1072 && infos [i].code == code)
1073 return infos [i].desc;
1074
1075 return "*unknown reason*";
1076}

◆ dumpContext()

unsigned long Athena::Signal::dumpContext ( IOFD fd,
char * buf,
unsigned int buf_size,
const void * context )
static

Utility function to dump the process context, as obtained for instance through signal handler parameters, unix getcontext() or Windows GetThreadContext().

The output is written directly to the file descriptor fd, using buf as the formatting buffer.

Returns SP if we can find it, else null.

Definition at line 1210 of file SealSignal.cxx.

1211{
1212 unsigned long sp = 0;
1213#if defined _WIN32 && defined _M_IX86
1214 const CONTEXT *uc = static_cast<const CONTEXT *> (context);
1215 sp = uc->Esp;
1216 MYWRITE (fd, buf, snprintf (buf, buf_size, "\n"
1217 "\n eip: %04lx:%08lx eflags: %08lx"
1218 "\n eax: %08lx ebx: %08lx"
1219 " ecx: %08lx edx: %08lx"
1220 "\n esi: %08lx edi: %08lx"
1221 " ebp: %08lx esp: %08lx"
1222 "\n ds: %04lx es: %04lx"
1223 " fs: %04lx ss: %04lx",
1224 uc->SegCs, uc->Eip, uc->EFlags,
1225 uc->Eax, uc->Ebx, uc->Ecx, uc->Edx,
1226 uc->Esi, uc->Edi, uc->Ebp, uc->Esp,
1227 uc->SegDs, uc->SegEs, uc->SegFs, uc->SegSs));
1228
1229 MYWRITE (fd, buf, snprintf (buf, buf_size,
1230 "\n FPU: control = %08lx"
1231 "\n status = %08lx"
1232 "\n tag = %08lx"
1233 "\n ip = %04lx:%08lx"
1234 "\n data = %04lx:%08lx"
1235 "\n state = %08lx",
1236 uc->FloatSave.ControlWord,
1237 uc->FloatSave.StatusWord,
1238 uc->FloatSave.TagWord,
1239 uc->FloatSave.ErrorSelector,
1240 uc->FloatSave.ErrorOffset,
1241 uc->FloatSave.DataSelector,
1242 uc->FloatSave.DataOffset,
1243 uc->FloatSave.Cr0NpxState));
1244
1245 for (int i = 0; i < 8; ++i)
1246 MYWRITE (fd, buf, snprintf (buf, buf_size.
1247 "\n %%fp%d = [%02x%02x:%02x%02x%02x%02x"
1248 "%02x%02x%02x%02x]",
1249 i,
1250 uc->FloatSave.RegisterArea [i * 10 + 0],
1251 uc->FloatSave.RegisterArea [i * 10 + 1],
1252 uc->FloatSave.RegisterArea [i * 10 + 2],
1253 uc->FloatSave.RegisterArea [i * 10 + 3],
1254 uc->FloatSave.RegisterArea [i * 10 + 4],
1255 uc->FloatSave.RegisterArea [i * 10 + 5],
1256 uc->FloatSave.RegisterArea [i * 10 + 6],
1257 uc->FloatSave.RegisterArea [i * 10 + 7],
1258 uc->FloatSave.RegisterArea [i * 10 + 8],
1259 uc->FloatSave.RegisterArea [i * 10 + 9]));
1260 MYWRITE (fd, "\n", 1);
1261
1262#elif HAVE_POSIX_SIGNALS
1263 // FIXME: how much of this is defined in POSIX or ABIs?
1264 const ucontext_t *uc = static_cast<const ucontext_t *> (context);
1265 const mcontext_t *mc = &uc->uc_mcontext;
1266 MYWRITE (fd, buf, snprintf (buf, buf_size, " stack = (%x, %x, %p)",
1267 uc->uc_stack.ss_flags,
1268 unsigned(uc->uc_stack.ss_size),
1269 uc->uc_stack.ss_sp));
1270
1271 MYWRITE (fd, "\n", 1);
1272#if defined __i386 && defined __linux
1273# if !defined REG_CS && defined CS
1274# define REG_CS CS
1275# define REG_DS DS
1276# define REG_ES ES
1277# define REG_FS FS
1278# define REG_SS SS
1279# define REG_EIP EIP
1280# define REG_EFL EFL
1281# define REG_EAX EAX
1282# define REG_EBX EBX
1283# define REG_ECX ECX
1284# define REG_EDX EDX
1285# define REG_ESI ESI
1286# define REG_EDI EDI
1287# define REG_EBP EBP
1288# define REG_ESP ESP
1289# define REG_UESP UESP
1290# define REG_TRAPNO TRAPNO
1291# define REG_ERR ERR
1292# endif
1293 sp = mc->gregs[REG_ESP];
1294 MYWRITE (fd, buf, snprintf (buf, buf_size,
1295 "\n eip: %04x:%08x eflags: %08x"
1296 "\n eax: %08x ebx: %08x"
1297 " ecx: %08x edx: %08x"
1298 "\n esi: %08x edi: %08x"
1299 " ebp: %08x esp: %08x"
1300 "\n ds: %04x es: %04x"
1301 " fs: %04x ss: %04x",
1302 mc->gregs [REG_CS] & 0xffff, mc->gregs [REG_EIP],
1303 mc->gregs [REG_EFL],
1304 mc->gregs [REG_EAX], mc->gregs [REG_EBX],
1305 mc->gregs [REG_ECX], mc->gregs [REG_EDX],
1306 mc->gregs [REG_ESI], mc->gregs [REG_EDI],
1307 mc->gregs [REG_EBP], mc->gregs [REG_ESP],
1308 mc->gregs [REG_DS] & 0xffff,
1309 mc->gregs [REG_ES] & 0xffff,
1310 mc->gregs [REG_FS] & 0xffff,
1311 mc->gregs [REG_SS] & 0xffff));
1312
1313 MYWRITE (fd, buf, snprintf (buf, buf__size,
1314 "\n\n signal esp: %08x"
1315 " trap: %d/%d"
1316 " oldmask: %08lx cr2: %08lx",
1317 mc->gregs [REG_UESP],
1318 mc->gregs [REG_TRAPNO], mc->gregs [REG_ERR],
1319 mc->oldmask, mc->cr2));
1320
1321 if (mc->fpregs)
1322 {
1323 MYWRITE (fd, buf, snprintf (buf, buf_size,
1324 "\n"
1325 "\n FPU: control = %08lx"
1326 "\n status = %08lx"
1327 "\n tag = %08lx"
1328 "\n ip = %04lx:%08lx"
1329 "\n data = %04lx:%08lx"
1330 "\n state = %08lx",
1331 mc->fpregs->cw, mc->fpregs->sw, mc->fpregs->tag,
1332 mc->fpregs->cssel & 0xffff, mc->fpregs->ipoff,
1333 mc->fpregs->datasel & 0xffff, mc->fpregs->dataoff,
1334 mc->fpregs->status));
1335
1336 for (int i = 0; i < 8; ++i)
1337 MYWRITE (fd, buf, snprintf (buf, buf_size,
1338 "\n %%fp%d = [%04hx:%04hx%04hx%04hx%04hx]",
1339 i,
1340 mc->fpregs->_st [i].exponent,
1341 mc->fpregs->_st [i].significand [0],
1342 mc->fpregs->_st [i].significand [1],
1343 mc->fpregs->_st [i].significand [2],
1344 mc->fpregs->_st [i].significand [3]));
1345 }
1346
1347#elif defined __x86_64__ && defined __linux
1348 sp = mc->gregs[REG_RSP];
1349 MYWRITE (fd, buf, snprintf (buf, buf_size,
1350 "\n rip: %04x:%016llx eflags: %016llx"
1351 "\n rax: %016llx rbx: %016llx"
1352 "\n rcx: %016llx rdx: %016llx"
1353 "\n r08: %016llx r09: %016llx"
1354 "\n r10: %016llx r11: %016llx"
1355 "\n r12: %016llx r13: %016llx"
1356 "\n r14: %016llx r15: %016llx"
1357 "\n rsi: %016llx rdi: %016llx"
1358 "\n rbp: %016llx rsp: %016llx"
1359 "\n gs: %04x fs: %04x",
1360 (unsigned)mc->gregs [REG_CSGSFS] & 0xffff,
1361 (unsigned long long)mc->gregs [REG_RIP],
1362 (unsigned long long)mc->gregs [REG_EFL],
1363 (unsigned long long)mc->gregs [REG_RAX],
1364 (unsigned long long)mc->gregs [REG_RBX],
1365 (unsigned long long)mc->gregs [REG_RCX],
1366 (unsigned long long)mc->gregs [REG_RDX],
1367 (unsigned long long)mc->gregs [REG_R8],
1368 (unsigned long long)mc->gregs [REG_R9],
1369 (unsigned long long)mc->gregs [REG_R10],
1370 (unsigned long long)mc->gregs [REG_R11],
1371 (unsigned long long)mc->gregs [REG_R12],
1372 (unsigned long long)mc->gregs [REG_R13],
1373 (unsigned long long)mc->gregs [REG_R14],
1374 (unsigned long long)mc->gregs [REG_R15],
1375 (unsigned long long)mc->gregs [REG_RSI],
1376 (unsigned long long)mc->gregs [REG_RDI],
1377 (unsigned long long)mc->gregs [REG_RBP],
1378 (unsigned long long)mc->gregs [REG_RSP],
1379 (unsigned)(mc->gregs [REG_CSGSFS]>>16) & 0xffff,
1380 (unsigned)(mc->gregs [REG_CSGSFS]>>32) & 0xffff));
1381
1382 MYWRITE (fd, buf, snprintf (buf, buf_size,
1383 "\n\n"
1384 " trap: %llu/%llu"
1385 " oldmask: %16llx cr2: %016llx",
1386 (unsigned long long)mc->gregs [REG_TRAPNO],
1387 (unsigned long long)mc->gregs [REG_ERR],
1388 (unsigned long long)mc->gregs [REG_OLDMASK],
1389 (unsigned long long)mc->gregs [REG_CR2]));
1390
1391 if (mc->fpregs)
1392 {
1393 MYWRITE (fd, buf, snprintf (buf, buf_size,
1394 "\n"
1395 "\n FPU: control = %04x"
1396 "\n status = %04x"
1397 "\n tag = %02x"
1398 "\n op = %04x"
1399 "\n ip = %016lx"
1400 "\n data = %016lx"
1401 "\n mxcsr = %08x"
1402 "\n mxcr_mask= %08x",
1403 mc->fpregs->cwd,
1404 mc->fpregs->swd,
1405 mc->fpregs->ftw,
1406 mc->fpregs->fop,
1407 mc->fpregs->rip,
1408 mc->fpregs->rdp,
1409 mc->fpregs->mxcsr,
1410 mc->fpregs->mxcr_mask));
1411
1412 for (int i = 0; i < 8; ++i)
1413 MYWRITE (fd, buf, snprintf (buf, buf_size,
1414 "\n %%fp%d = [%04hx:%04hx%04hx%04hx%04hx]",
1415 i,
1416 mc->fpregs->_st [i].exponent,
1417 mc->fpregs->_st [i].significand [0],
1418 mc->fpregs->_st [i].significand [1],
1419 mc->fpregs->_st [i].significand [2],
1420 mc->fpregs->_st [i].significand [3]));
1421
1422 for (int i = 0; i < 16; ++i)
1423 MYWRITE (fd, buf, snprintf (buf, buf_size,
1424 "\n %%xmm%02d = [%08x %08x %08x %08x]",
1425 i,
1426 mc->fpregs->_xmm[i].element[0],
1427 mc->fpregs->_xmm[i].element[1],
1428 mc->fpregs->_xmm[i].element[2],
1429 mc->fpregs->_xmm[i].element[3]));
1430 }
1431
1432#elif __APPLE__ && defined __ppc__
1433 MYWRITE (fd, buf, snprintf (buf, buf_size, "\n dar: %08lx dsisr: %08lx exception: %08lx",
1434 (*mc)->es.dar, (*mc)->es.dsisr, (*mc)->es.exception));
1435
1436 MYWRITE (fd, buf, snprintf (buf, buf_size,
1437 "\n srr0: %08x srr1: %08x cr: %08x xer: %08x"
1438 "\n lr: %08x ctr: %08x vrsave: %08x fpscr: %08x",
1439 (*mc)->ss.srr0, (*mc)->ss.srr1, (*mc)->ss.cr, (*mc)->ss.xer,
1440 (*mc)->ss.lr, (*mc)->ss.ctr, (*mc)->ss.vrsave, (*mc)->fs.fpscr));
1441
1442 MYWRITE (fd, buf, snprintf (buf, buf_size, "\n vrvalid: %08x vscr: %08lx:%08lx:%08lx:%08lx\n",
1443 (*mc)->vs.save_vrvalid,
1444 (*mc)->vs.save_vscr [0], (*mc)->vs.save_vscr [1],
1445 (*mc)->vs.save_vscr [2], (*mc)->vs.save_vscr [3]));
1446
1447 for (unsigned int *regs = &(*mc)->ss.r0, i = 0; i < 32; i += 4)
1448 MYWRITE (fd, buf, snprintf (buf, buf_size, "\n r%-2d %08x r%-2d %08x r%-2d %08x r%-2d %08x",
1449 i, regs [i], i+1, regs [i+1], i+2, regs [i+2], i+3, regs [i+3]));
1450 for (int i = 0; i < 32; ++i)
1451 MYWRITE (fd, buf, snprintf (buf, buf_size, "\n fp%-2d %016qx (%f)", i,
1452 *(unsigned long long *) &(*mc)->fs.fpregs [i],
1453 (*mc)->fs.fpregs [i]));
1454 for (int i = 0; i < 32; ++i)
1455 MYWRITE (fd, buf, snprintf (buf, buf_size, "\n vr%-2d %08lx:%08lx:%08lx:%08lx", i,
1456 (*mc)->vs.save_vr[i][0], (*mc)->vs.save_vr[i][1],
1457 (*mc)->vs.save_vr[i][2], (*mc)->vs.save_vr[i][3]));
1458#elif defined __aarch64__ && defined __linux
1459 CxxUtils::aarch64_dump_registers (fd, buf, buf_size, *mc);
1460#elif __sun
1461 for (int i = 0; i < NGREG; i++)
1462 MYWRITE (fd, buf, snprintf (buf, buf_size, "%s %%r%02d = %08x",
1463 i % 4 == 0 ? "\n" : "", i, mc->gregs [i]));
1464#else
1465 dumpMemory (fd, buf, buf_size, mc, sizeof (*mc));
1466#endif // __i386 && __linux, __sun, other
1467
1468 MYWRITE (fd, "\n", 1);
1469#endif // HAVE_POSIX_SIGNALS
1470
1471 return sp;
1472}
static Double_t sp
#define MYWRITE(fd, data, n)
static void dumpMemory(IOFD fd, char *buf, unsigned int buf_size, const void *data, size_t n)
Utility function to dump memory section from data for n bytes.
static char buf[SIGNAL_MESSAGE_BUFSIZE]
Dump application state information on a fatal signal.

◆ dumpInfo()

void Athena::Signal::dumpInfo ( IOFD fd,
char * buf,
unsigned int buf_size,
int sig,
const siginfo_t * info )
static

Utility function to dump the signal info descriptor for signal sig, as obtained for instance through signal handler parameters or wait().

The output is written directly to the file descriptor fd, using buf as the formatting buffer.

Definition at line 1083 of file SealSignal.cxx.

1084{
1085 if (! info)
1086 return;
1087
1088#ifdef _WIN32
1089# define DOCODE(x) case x: name = #x
1090 // NB: siginfo_t == EXCEPTION_RECORD.
1091 const char *name = 0;
1092
1093 switch (info->ExceptionCode)
1094 {
1095 DOCODE(STATUS_ABANDONED_WAIT_0);
1096 DOCODE(STATUS_ACCESS_VIOLATION);
1097 DOCODE(STATUS_ARRAY_BOUNDS_EXCEEDED);
1098 DOCODE(STATUS_BREAKPOINT);
1099 DOCODE(STATUS_CONTROL_C_EXIT);
1100 DOCODE(STATUS_DATATYPE_MISALIGNMENT);
1101 DOCODE(STATUS_FLOAT_DENORMAL_OPERAND);
1102 DOCODE(STATUS_FLOAT_DIVIDE_BY_ZERO);
1103 DOCODE(STATUS_FLOAT_INEXACT_RESULT);
1104 DOCODE(STATUS_FLOAT_INVALID_OPERATION);
1105 DOCODE(STATUS_FLOAT_OVERFLOW);
1106 DOCODE(STATUS_FLOAT_STACK_CHECK);
1107 DOCODE(STATUS_FLOAT_UNDERFLOW);
1108 DOCODE(STATUS_GUARD_PAGE_VIOLATION);
1109 DOCODE(STATUS_ILLEGAL_INSTRUCTION);
1110 DOCODE(STATUS_INTEGER_DIVIDE_BY_ZERO);
1111 DOCODE(STATUS_INTEGER_OVERFLOW);
1112 DOCODE(STATUS_INVALID_DISPOSITION);
1113 DOCODE(STATUS_IN_PAGE_ERROR);
1114 DOCODE(STATUS_NONCONTINUABLE_EXCEPTION);
1115 DOCODE(STATUS_NO_MEMORY);
1116 DOCODE(STATUS_PENDING);
1117 DOCODE(STATUS_PRIVILEGED_INSTRUCTION);
1118 DOCODE(STATUS_SINGLE_STEP);
1119 DOCODE(STATUS_STACK_OVERFLOW);
1120 DOCODE(STATUS_TIMEOUT);
1121 DOCODE(STATUS_USER_APC);
1122 DOCODE(STATUS_WAIT_0);
1123 }
1124 // -> DWORD ExceptionCode
1125 // -> DWORD ExceptionFlags
1126 // -> EXCEPTION_RECORD *ExceptionRecord
1127 // -> PVOID ExceptionAddress
1128 // -> DWORD NumberParameters
1129 // -> DWORD ExceptionInfo [MAX_PARAMETERS (15)]
1130 if (name)
1131 MYWRITE (fd, buf, snprintf (buf, buf_size, "Exception: %s\n", name));
1132 else
1133 MYWRITE (fd, buf, snprintf (buf, buf_size, "Exception %lu\n",
1134 info->ExceptionCode));
1135 MYWRITE (fd, buf, snprintf (buf, buf_size, " addr = %08lx", info->ExceptionAddress));
1136
1137#elif HAVE_POSIX_SIGNALS
1138 // These should always be set.
1139 MYWRITE (fd, buf, snprintf (buf, buf_size,
1140 " signo = %d, errno = %d, code = %d (%s)\n",
1141 info->si_signo, info->si_errno, info->si_code,
1142 describe (sig, info->si_code)));
1143
1144 // These are set if the signal was sent by kill, POSIX signal
1145 // send or SIGCHLD.
1146 //coverity[INCONSISTENT_UNION_ACCESS]
1147 MYWRITE (fd, buf, snprintf (buf, buf_size, " pid = %ld, uid = %ld\n",
1148 (long) info->si_pid, (long) info->si_uid));
1149
1150 // Child status for SIGCHLD.
1151 if (sig == SIGCHLD) {
1152 // Create temporary variables, as MacOS/clang doesn't want to
1153 // accept the on-the-fly conversion of the following variables
1154 // without printing some warnings.
1155 //coverity[INCONSISTENT_UNION_ACCESS]
1156 const long status = info->si_status;
1157 const long utime = info->si_utime;
1158 const long stime = info->si_stime;
1159 MYWRITE (fd, buf, snprintf (buf, buf_size,
1160 " status = %ld, utime = %ld, stime = %ld\n",
1161 status, utime, stime));
1162 }
1163
1164 // These are set if the POSIX signal sender passed them.
1165 //coverity[INCONSISTENT_UNION_ACCESS]
1166 MYWRITE (fd, buf, snprintf (buf, buf_size, " value = (%d, %p)\n",
1167 info->si_int, info->si_ptr));
1168
1169 // This is the interesting address for memory faults.
1170 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS)
1171 //coverity[INCONSISTENT_UNION_ACCESS]
1172 MYWRITE (fd, buf, snprintf (buf, buf_size, " addr = %p\n", info->si_addr));
1173
1174# ifdef SIGPOLL // not darwin
1175 // SIGPOLL status data.
1176 if (sig == SIGPOLL)
1177 //coverity[INCONSISTENT_UNION_ACCESS]
1178 MYWRITE (fd, buf, snprintf (buf, buf_size, " band = %ld, fd = %d\n",
1179 (long) info->si_band, info->si_fd));
1180# endif
1181#endif // HAVE_POSIX_SIGNALS
1182}
static const char * name(int sig)
Return the name of the signal number sig.
static const char * describe(int sig, int code)
Return the description for signal info code code for signal number sig.
std::string stime()
return the current data and time
status
Definition merge.py:16

◆ dumpMemory()

void Athena::Signal::dumpMemory ( IOFD fd,
char * buf,
unsigned int buf_size,
const void * data,
size_t n )
static

Utility function to dump memory section from data for n bytes.

Used to dump machine context on platforms where we don't know any better. The output is written directly to the file descriptor fd, using buf as the formatting buffer.

Definition at line 1189 of file SealSignal.cxx.

1190{
1191 for (size_t i = 0; i < n; )
1192 {
1193 size_t m = snprintf (buf, buf_size, "\n ");
1194 for (size_t j = 0; i < n && j < 32; ++j, ++i)
1195 m += snprintf (buf + m, buf_size-m, "%s%02x",
1196 j % 4 == 0 ? " " : "",
1197 (unsigned int) (((const unsigned char *) data) [i]));
1198
1199 MYWRITE (fd, buf, m);
1200 }
1201}
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)

◆ handle()

Signal::HandlerType Athena::Signal::handle ( int sig,
HandlerType handler,
const sigset_t * blockMask = 0 )
static

Install a new signal handler handler for signal number sig and returns the old handler.

This method uses the POSIX signal handling primitives if they are available, failing which falling back to the C standard signal() function.

When POSIX signals are used, signals other than sig are blocked according to blockMask (if null, no change is made) during the execution of handler. Note that the signal itself is always blocked during the handler execution and need not be mentioned in the mask explicitly. System calls are made restartable although this has little impact as this library always restarts interrupted system calls automatically despite the signal handling settings.

(FIXME: Expose option SA_NOCLDSTOP, SA_ONSTACK?) (FIXME: Threads vs. signals)

Definition at line 276 of file SealSignal.cxx.

277{
278 assert (sig > 0 && sig < NSIG);
279 // LOG (0, trace, LFsignal, "[" << sig << "] (" << name (sig) << ") = "
280 // << (void *) handler << '\n'); // wlav
281
282 HandlerType oldhandler;
283#if !HAVE_POSIX_SIGNALS || !SA_SIGINFO
284 // Switch to using trampoline if we don't have the necessary
285 // arguments. FIXME: multiple threads; WIN32?
286 oldhandler = s_trampolines [sig];
287 if (handler == (HandlerType) SIG_IGN || handler == (HandlerType) SIG_DFL)
288 s_trampolines [sig] = 0;
289 else
290 {
293 }
294#endif
295
296 // Set the handler
297#if HAVE_POSIX_SIGNALS
298 struct sigaction old, act;
299 STDC::memset (&act, 0, sizeof (act));
300 STDC::memset (&old, 0, sizeof (old));
301 act.sa_flags = SA_RESTART | SA_SIGINFO;
302 act.sa_sigaction = handler;
303 sigemptyset (&act.sa_mask);
304 if (blockMask)
305 act.sa_mask = *blockMask;
306 else if (sigaction (sig, &old, 0) == 0)
307 act.sa_mask = old.sa_mask;
308 else
309 sigemptyset (&act.sa_mask);
310
311 // There isn't much we can do to check the return status. We get
312 // called in all sorts fragile places like signal handlers, and
313 // those are not the place for throwing exceptions or asserting.
314 if (sigaction (sig, &act, &old) == -1)
315 return (HandlerType) (void*)SIG_ERR;
316 oldhandler = (HandlerType) old.sa_sigaction;
317#else // ! HAVE_POSIX_SIGNALS
318 (HandlerType) ::signal (sig, (DummyHandlerType) handler);
319#endif // HAVE_POSIX_SIGNALS
320 return oldhandler;
321}
static HandlerType handler(int sig, sigset_t *mask=0)
Return the current handler for signal number sig and its blocked signals in mask (if non-null).
static void trampoline(int sig)
Internal signal handler trampoline to convert handler arguments to look more like POSIX signals.
static HandlerType s_trampolines[NSIG]
Actual signal handlers when POSIX signals are not available.
Definition SealSignal.h:283
void(* HandlerType)(int sig, siginfo_t *info, void *extra)
Signal handler type.
Definition SealSignal.h:196
void(* DummyHandlerType)(int)
Dummy handler type for standard signal() function.

◆ handler()

Signal::HandlerType Athena::Signal::handler ( int sig,
sigset_t * mask = 0 )
static

Return the current handler for signal number sig and its blocked signals in mask (if non-null).

Definition at line 235 of file SealSignal.cxx.

236{
237 assert (sig > 0 && sig < NSIG);
238
239 // Get the handler
240#if HAVE_POSIX_SIGNALS
241 struct sigaction old;
242 STDC::memset (&old, 0, sizeof (old));
243 if (sigaction (sig, &old, 0) == 0)
244 {
245 if (mask)
246 *mask = old.sa_mask;
247 return (HandlerType) (void*) old.sa_handler;
248 }
249 else
250 return (HandlerType) (void*)SIG_ERR;
251#else // ! HAVE_POSIX_SIGNALS
252 HandlerType old = (HandlerType) signal (sig, SIG_DFL);
253 signal (sig, (DummyHandlerType) old);
254 return old;
255#endif // HAVE_POSIX_SIGNALS
256}

◆ ignore()

void Athena::Signal::ignore ( int sig)
static

Ignore the signal number sig.

Definition at line 330 of file SealSignal.cxx.

331{ handle (sig, (HandlerType) (void*)SIG_IGN); }
static HandlerType handle(int sig, HandlerType handler, const sigset_t *blockMask=0)
Install a new signal handler handler for signal number sig and returns the old handler.

◆ kill()

int Athena::Signal::kill ( pid_t process,
int sig )
static

Send the signal sig to process identified by process.

Implemented only on unixen.

Definition at line 388 of file SealSignal.cxx.

389{
390 // FIXME: sending signals to threads?
391#ifndef _WIN32
392 return ::kill (process, sig);
393#else
394 return 0;
395#endif
396}
const std::string process

◆ mask()

void Athena::Signal::mask ( const sigset_t * mask,
sigset_t * old = 0 )
static

Set the list of currently blocked signals to mask and return the old setting in old (if non-null).

This function is implemented only on systems with POSIX signals.

Definition at line 364 of file SealSignal.cxx.

365{
366#if HAVE_POSIX_SIGNALS
367 // FIXME: threads -- need to use pthread_sigmask
368 sigprocmask (SIG_SETMASK, mask, old);
369#endif
370}

◆ name()

const char * Athena::Signal::name ( int sig)
static

Return the name of the signal number sig.

The returned memory is statically allocated and must not be freed.

Definition at line 215 of file SealSignal.cxx.

216{
217#if HAVE_STRSIGNAL
218 return strsignal (sig);
219#elif HAVE_SYS_SIGLIST
220 return sys_siglist [sig];
221#else
222 // This is not thread safe. But if you have threads, you probably
223 // have strsignal() as well (FIXME: check WIN32).
224 static const int buf_size = 8 + BitTraits<int>::Digits;
225 static char buf [NSIG] [buf_size];
226 if (! buf [sig][0])
227 snprintf (buf [sig], buf_size, "Signal %d", sig);
228 return buf [sig];
229#endif
230}

◆ pending() [1/2]

bool Athena::Signal::pending ( int sig)
static

Check if sig is pending for this process.

Definition at line 470 of file SealSignal.cxx.

471{ sigset_t s; pending (&s); return sigismember (&s, sig); }
#define sigismember(x, y)
Definition SealSignal.h:86
static bool pending(int sig)
Check if sig is pending for this process.

◆ pending() [2/2]

void Athena::Signal::pending ( sigset_t * mask)
static

Return in mask the list of signals pending for this process.

Definition at line 483 of file SealSignal.cxx.

484{
485}

◆ queue() [1/4]

int Athena::Signal::queue ( int sig,
int value = 0 )
static

Queue signal sig for this process with additional data value.

Implemented only on systems with POSIX real-time signals.

Definition at line 445 of file SealSignal.cxx.

446{
447 return 0;
448}

◆ queue() [2/4]

int Athena::Signal::queue ( int sig,
void * value )
static

Queue signal sig for this process with additional data value.

Implemented only on systems with POSIX real-time signals.

Definition at line 462 of file SealSignal.cxx.

463{
464 return 0;
465}

◆ queue() [3/4]

int Athena::Signal::queue ( pid_t process,
int sig,
int value = 0 )
static

Queue signal sig with additional data value for process.

Implemented only on systems with POSIX real-time signals.

Definition at line 410 of file SealSignal.cxx.

411{
412 return 0;
413}

◆ queue() [4/4]

int Athena::Signal::queue ( pid_t process,
int sig,
void * value )
static

Queue signal sig with additional data value for process.

Implemented only on systems with POSIX real-time signals.

Definition at line 428 of file SealSignal.cxx.

429{
430 return 0;
431}

◆ raise()

int Athena::Signal::raise ( int sig)
static

Raise the signal number sig.

Returns the exit code from the raise() system call (or kill() if raise() does not exist).

Definition at line 376 of file SealSignal.cxx.

377{
378#if HAVE_RAISE
379 return ::raise (sig);
380#else
381 return ::kill (getpid (), sig);
382#endif
383}

◆ revert()

void Athena::Signal::revert ( int sig)
static

Revert the signal number sig back to its default behaviour.

Definition at line 325 of file SealSignal.cxx.

326{ handle (sig, (HandlerType) (void*)SIG_DFL); }

◆ suspend()

void Athena::Signal::suspend ( const sigset_t * mask)
static

Temporarily replace the signal mask of the process with mask and then suspend until a signal is received.

Definition at line 499 of file SealSignal.cxx.

500{
501}

◆ trampoline()

void Athena::Signal::trampoline ( int sig)
staticprivate

Internal signal handler trampoline to convert handler arguments to look more like POSIX signals.

The actual handler must have been installed into s_trampolines by handle().

Definition at line 202 of file SealSignal.cxx.

203{
204 assert (sig > 0 && sig < NSIG);
205 assert (s_trampolines [sig]);
206 siginfo_t info;
207 memset (&info, 0, sizeof (info));
208 s_trampolines [sig] (sig, &info, 0);
209}

◆ wait() [1/2]

int Athena::Signal::wait ( const sigset_t * mask,
siginfo_t * info = 0,
long msecs = -1 )
static

Suspend the thread waiting for signals specified by mask for at most msecs milliseconds.

If msecs is negative (the default), waits until a signal is delivered. Otherwise waits up to the specified time limit. Returns the number of the signal that was received, or -1 if the time limit expired. If info is given, fills it with the information that the handler would have otherwise been given. Note that the signals must be blocked (in a multi-threaded application in all the threads, not just the calling one) and not be ignored before calling this function; if a handler is registered, it won't be called. Implemented only on systems with POSIX real-time signals.

Definition at line 561 of file SealSignal.cxx.

564{
565 return 0;
566}

◆ wait() [2/2]

bool Athena::Signal::wait ( int sig,
siginfo_t * info = 0,
long msecs = -1 )
static

Suspend the thread waiting for signal sig at most msecs milliseconds.

If msecs is negative (the default), waits until a signal is delivered. Otherwise waits up to the specified time limit. Returns true if the signal was received. Note that the signal must be blocked (in a multi-threaded application in all the threads, not just the calling one) and not be ignored before calling this function; if a handler is registered, it won't be called. Implemented only on systems with POSIX real-time signals.

Definition at line 514 of file SealSignal.cxx.

515{
516 sigset_t s;
517 sigemptyset (&s);
518 sigaddset (&s, sig);
519 // cppcheck-suppress uninitvar
520 return wait (&s, info, msecs) == sig;
521}
static bool wait(int sig, siginfo_t *info=0, long msecs=-1)
Suspend the thread waiting for signal sig at most msecs milliseconds.

Member Data Documentation

◆ FATAL_AUTO_EXIT

const int Athena::Signal::FATAL_AUTO_EXIT = 256
static

Option to make #fatal(int, siginfo_t *, void *) exit via #quit(int , siginfo_t *, void *).

This will cause all the application clean-up hook to run.

Definition at line 142 of file SealSignal.h.

◆ FATAL_DEFAULT

const int Athena::Signal::FATAL_DEFAULT
static
Initial value:
static const int FATAL_DUMP_CONTEXT
Option to make fataldump(int, siginfo_t *, void *) (invoked by fatal(int, siginfo_t *,...
Definition SealSignal.h:138
static const int FATAL_AUTO_EXIT
Option to make fatal(int, siginfo_t *, void *) exit via quit(int , siginfo_t *, void *).
Definition SealSignal.h:142
static const int FATAL_DUMP_CORE
Option to make fatal(int, siginfo_t *, void *) dump a core file before crashing.
Definition SealSignal.h:122
static const int FATAL_DUMP_LIBS
Option to make fataldump(int sig, siginfo_t *, void *) (invoked by fatal(int, siginfo_t *,...
Definition SealSignal.h:134
static const int USR1_DUMP_CORE
Option that instructs fatal(int, siginfo_t *, void *) to call coredump() on SIGUSR1.
Definition SealSignal.h:111
static const int FATAL_DUMP_SIG
Option to make fataldump(int, siginfo_t *, void *) (invoked by fatal(int, siginfo_t *,...
Definition SealSignal.h:126
static const int FATAL_DUMP_STACK
Option to make fataldump(int, siginfo_t *, void *) (invoked by fatal(int, siginfo_t *,...
Definition SealSignal.h:130
static const int FATAL_ON_INT
Option to make SIGINT fatal.
Definition SealSignal.h:119

Default options to #handleFatal(const char *, IOFD fd, FatalHook, FatalReturn, unsigned.

Definition at line 145 of file SealSignal.h.

◆ FATAL_DUMP_CONTEXT

const int Athena::Signal::FATAL_DUMP_CONTEXT = 128
static

Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *, void *)) to dump the machine context (registers etc.) from the fault position.

Definition at line 138 of file SealSignal.h.

◆ FATAL_DUMP_CORE

const int Athena::Signal::FATAL_DUMP_CORE = 8
static

Option to make #fatal(int, siginfo_t *, void *) dump a core file before crashing.

Definition at line 122 of file SealSignal.h.

◆ FATAL_DUMP_LIBS

const int Athena::Signal::FATAL_DUMP_LIBS = 64
static

Option to make #fataldump(int sig, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *, void *)) to dump the list of currently loaded shared libraries.

Definition at line 134 of file SealSignal.h.

◆ FATAL_DUMP_SIG

const int Athena::Signal::FATAL_DUMP_SIG = 16
static

Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *, void *)) to dump the signal name (as reported by name()).

Definition at line 126 of file SealSignal.h.

◆ FATAL_DUMP_STACK

const int Athena::Signal::FATAL_DUMP_STACK = 32
static

Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *, void *)) to dump stack backtrace for the offending code location.

Definition at line 130 of file SealSignal.h.

◆ FATAL_ON_INT

const int Athena::Signal::FATAL_ON_INT = 4
static

Option to make SIGINT fatal.

It will still just quit, not crash.

Definition at line 119 of file SealSignal.h.

◆ FATAL_ON_QUIT

const int Athena::Signal::FATAL_ON_QUIT = 2
static

Option to make SIGHUP, SIGTERM and SIGQUIT fatal instead of just #quit(int , siginfo_t *, void *) signals.

Definition at line 115 of file SealSignal.h.

◆ s_applicationName

const char * Athena::Signal::s_applicationName = 0
staticprivate

The current application name.

Definition at line 276 of file SealSignal.h.

◆ s_crashed

bool Athena::Signal::s_crashed = false
staticprivate

Indicator that the application has been crashed: that a fatal signal has been delivered.

Definition at line 273 of file SealSignal.h.

◆ s_fatalFd

IOFD Athena::Signal::s_fatalFd = IOFD_INVALID
staticprivate

The output file descriptor for #fataldump().

Definition at line 277 of file SealSignal.h.

◆ s_fatalHook

Signal::FatalHook Athena::Signal::s_fatalHook = 0
staticprivate

The application handler hook for fatal signals.

Definition at line 278 of file SealSignal.h.

◆ s_fatalOptions

unsigned Athena::Signal::s_fatalOptions = 0
staticprivate

The current fatal signal handling options.

Definition at line 280 of file SealSignal.h.

◆ s_fatalReturn

Signal::FatalReturn Athena::Signal::s_fatalReturn = 0
staticprivate

The application main return hook for fatal signals.

Definition at line 279 of file SealSignal.h.

◆ s_inFatal

int Athena::Signal::s_inFatal = 0
staticprivate

Indicator that we are currently executing inside #fatal().

Used to protect against signals delivered during recovery attempts.

Definition at line 274 of file SealSignal.h.

◆ s_lastSP

std::atomic< unsigned long > Athena::Signal::s_lastSP
staticprivate

Used to switch to a raw stack dump if we crash during a backtrace.

Definition at line 275 of file SealSignal.h.

◆ s_quitHook

Signal::QuitHook Athena::Signal::s_quitHook = 0
staticprivate

The application handler hook for quitting-related signals.

Definition at line 281 of file SealSignal.h.

◆ s_trampolines

Signal::HandlerType Athena::Signal::s_trampolines
staticprivate

Actual signal handlers when POSIX signals are not available.

These are required so that we can send pass correct (= null) arguments to the registered handler when the system is not passing anything, or garbage. If this happens, handle() will register trampoline() as the signal handler and register the signal in this table, and trampoline just looks the actual handler here.

Definition at line 283 of file SealSignal.h.

◆ USR1_DUMP_CORE

const int Athena::Signal::USR1_DUMP_CORE = 1
static

Option that instructs #fatal(int, siginfo_t *, void *) to call #coredump() on SIGUSR1.

This is merely a request to drop a core; no attempt is made to guarantee success. Failure may result for example for lack of permissions, for lack of disk space, or due to low resource limits. Please note that core files can only be created on unixen. Note also that dropping a core is a security risk and should never be enabled in setuid or setgid programs or for production applications.

Definition at line 111 of file SealSignal.h.


The documentation for this class was generated from the following files: