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]

void quit 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]

bool fatalDump 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]

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

◆ ATLAS_NOT_THREAD_SAFE() [8/13]

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

◆ ATLAS_NOT_THREAD_SAFE() [9/13]

FatalHook handleFatalHook 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]

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

◆ ATLAS_NOT_THREAD_SAFE() [12/13]

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

◆ ATLAS_NOT_THREAD_SAFE() [13/13]

bool crashed 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 353 of file SealSignal.cxx.

354{
355#if HAVE_POSIX_SIGNALS
356 // FIXME: threads -- need to use pthread_sigmask
357 sigprocmask (sense ? SIG_BLOCK : SIG_UNBLOCK, mask, 0);
358#endif
359}
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 338 of file SealSignal.cxx.

339{
340#if HAVE_POSIX_SIGNALS
341 // FIXME: threads -- need to use pthread_sigmask
343 sigemptyset (&mask);
344 sigaddset (&mask, sig);
345 block (&mask, sense);
346#endif
347}
#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 968 of file SealSignal.cxx.

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

◆ 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 1206 of file SealSignal.cxx.

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

1085{
1086 if (! info)
1087 return;
1088
1089#ifdef _WIN32
1090# define DOCODE(x) case x: name = #x
1091 // NB: siginfo_t == EXCEPTION_RECORD.
1092 const char *name = 0;
1093
1094 switch (info->ExceptionCode)
1095 {
1096 DOCODE(STATUS_ABANDONED_WAIT_0);
1097 DOCODE(STATUS_ACCESS_VIOLATION);
1098 DOCODE(STATUS_ARRAY_BOUNDS_EXCEEDED);
1099 DOCODE(STATUS_BREAKPOINT);
1100 DOCODE(STATUS_CONTROL_C_EXIT);
1101 DOCODE(STATUS_DATATYPE_MISALIGNMENT);
1102 DOCODE(STATUS_FLOAT_DENORMAL_OPERAND);
1103 DOCODE(STATUS_FLOAT_DIVIDE_BY_ZERO);
1104 DOCODE(STATUS_FLOAT_INEXACT_RESULT);
1105 DOCODE(STATUS_FLOAT_INVALID_OPERATION);
1106 DOCODE(STATUS_FLOAT_OVERFLOW);
1107 DOCODE(STATUS_FLOAT_STACK_CHECK);
1108 DOCODE(STATUS_FLOAT_UNDERFLOW);
1109 DOCODE(STATUS_GUARD_PAGE_VIOLATION);
1110 DOCODE(STATUS_ILLEGAL_INSTRUCTION);
1111 DOCODE(STATUS_INTEGER_DIVIDE_BY_ZERO);
1112 DOCODE(STATUS_INTEGER_OVERFLOW);
1113 DOCODE(STATUS_INVALID_DISPOSITION);
1114 DOCODE(STATUS_IN_PAGE_ERROR);
1115 DOCODE(STATUS_NONCONTINUABLE_EXCEPTION);
1116 DOCODE(STATUS_NO_MEMORY);
1117 DOCODE(STATUS_PENDING);
1118 DOCODE(STATUS_PRIVILEGED_INSTRUCTION);
1119 DOCODE(STATUS_SINGLE_STEP);
1120 DOCODE(STATUS_STACK_OVERFLOW);
1121 DOCODE(STATUS_TIMEOUT);
1122 DOCODE(STATUS_USER_APC);
1123 DOCODE(STATUS_WAIT_0);
1124 }
1125 // -> DWORD ExceptionCode
1126 // -> DWORD ExceptionFlags
1127 // -> EXCEPTION_RECORD *ExceptionRecord
1128 // -> PVOID ExceptionAddress
1129 // -> DWORD NumberParameters
1130 // -> DWORD ExceptionInfo [MAX_PARAMETERS (15)]
1131 if (name)
1132 MYWRITE (fd, buf, snprintf (buf, buf_size, "Exception: %s\n", name));
1133 else
1134 MYWRITE (fd, buf, snprintf (buf, buf_size, "Exception %lu\n",
1135 info->ExceptionCode));
1136 MYWRITE (fd, buf, snprintf (buf, buf_size, " addr = %08lx", info->ExceptionAddress));
1137
1138#elif HAVE_POSIX_SIGNALS
1139 // These should always be set.
1140 MYWRITE (fd, buf, snprintf (buf, buf_size,
1141 " signo = %d, errno = %d, code = %d (%s)\n",
1142 info->si_signo, info->si_errno, info->si_code,
1143 describe (sig, info->si_code)));
1144
1145 // These are set if the signal was sent by kill, POSIX signal
1146 // send or SIGCHLD.
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 const long status = info->si_status;
1156 const long utime = info->si_utime;
1157 const long stime = info->si_stime;
1158 MYWRITE (fd, buf, snprintf (buf, buf_size,
1159 " status = %ld, utime = %ld, stime = %ld\n",
1160 status, utime, stime));
1161 }
1162
1163 // These are set if the POSIX signal sender passed them.
1164 MYWRITE (fd, buf, snprintf (buf, buf_size, " value = (%d, %p)\n",
1165 info->si_int, info->si_ptr));
1166
1167 // This is the interesting address for memory faults.
1168 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS)
1169 MYWRITE (fd, buf, snprintf (buf, buf_size, " addr = %p\n", info->si_addr));
1170
1171# ifdef SIGPOLL // not darwin
1172 // SIGPOLL status data.
1173 if (sig == SIGPOLL)
1174 MYWRITE (fd, buf, snprintf (buf, buf_size, " band = %ld, fd = %d\n",
1175 (long) info->si_band, info->si_fd));
1176# endif
1177#endif // HAVE_POSIX_SIGNALS
1178}
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 1185 of file SealSignal.cxx.

1186{
1187 for (size_t i = 0; i < n; )
1188 {
1189 size_t m = snprintf (buf, buf_size, "\n ");
1190 for (size_t j = 0; i < n && j < 32; ++j, ++i)
1191 m += snprintf (buf + m, buf_size-m, "%s%02x",
1192 j % 4 == 0 ? " " : "",
1193 (unsigned int) (((const unsigned char *) data) [i]));
1194
1195 MYWRITE (fd, buf, m);
1196 }
1197}
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11

◆ 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 277 of file SealSignal.cxx.

278{
279 assert (sig > 0 && sig < NSIG);
280 // LOG (0, trace, LFsignal, "[" << sig << "] (" << name (sig) << ") = "
281 // << (void *) handler << '\n'); // wlav
282
283 HandlerType oldhandler;
284#if !HAVE_POSIX_SIGNALS || !SA_SIGINFO
285 // Switch to using trampoline if we don't have the necessary
286 // arguments. FIXME: multiple threads; WIN32?
287 oldhandler = s_trampolines [sig];
288 if (handler == (HandlerType) SIG_IGN || handler == (HandlerType) SIG_DFL)
289 s_trampolines [sig] = 0;
290 else
291 {
294 }
295#endif
296
297 // Set the handler
298#if HAVE_POSIX_SIGNALS
299 struct sigaction old, act;
300 STDC::memset (&act, 0, sizeof (act));
301 STDC::memset (&old, 0, sizeof (old));
302 act.sa_flags = SA_RESTART | SA_SIGINFO;
303 act.sa_sigaction = handler;
304 sigemptyset (&act.sa_mask);
305 if (blockMask)
306 act.sa_mask = *blockMask;
307 else if (sigaction (sig, &old, 0) == 0)
308 act.sa_mask = old.sa_mask;
309 else
310 sigemptyset (&act.sa_mask);
311
312 // There isn't much we can do to check the return status. We get
313 // called in all sorts fragile places like signal handlers, and
314 // those are not the place for throwing exceptions or asserting.
315 if (sigaction (sig, &act, &old) == -1)
316 return (HandlerType) (void*)SIG_ERR;
317 oldhandler = (HandlerType) old.sa_sigaction;
318#else // ! HAVE_POSIX_SIGNALS
319 (HandlerType) ::signal (sig, (DummyHandlerType) handler);
320#endif // HAVE_POSIX_SIGNALS
321 return oldhandler;
322}
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 236 of file SealSignal.cxx.

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

◆ ignore()

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

Ignore the signal number sig.

Definition at line 331 of file SealSignal.cxx.

332{ 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 389 of file SealSignal.cxx.

390{
391 // FIXME: sending signals to threads?
392#ifndef _WIN32
393 return ::kill (process, sig);
394#else
395 return 0;
396#endif
397}
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 365 of file SealSignal.cxx.

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

◆ 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 216 of file SealSignal.cxx.

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

◆ pending() [1/2]

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

Check if sig is pending for this process.

Definition at line 471 of file SealSignal.cxx.

472{ 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 484 of file SealSignal.cxx.

485{
486}

◆ 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 446 of file SealSignal.cxx.

447{
448 return 0;
449}

◆ 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 463 of file SealSignal.cxx.

464{
465 return 0;
466}

◆ 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 411 of file SealSignal.cxx.

412{
413 return 0;
414}

◆ 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 429 of file SealSignal.cxx.

430{
431 return 0;
432}

◆ 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 377 of file SealSignal.cxx.

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

◆ revert()

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

Revert the signal number sig back to its default behaviour.

Definition at line 326 of file SealSignal.cxx.

327{ 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 500 of file SealSignal.cxx.

501{
502}

◆ 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 203 of file SealSignal.cxx.

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

◆ 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 562 of file SealSignal.cxx.

565{
566 return 0;
567}

◆ 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 515 of file SealSignal.cxx.

516{
517 sigset_t s;
518 sigemptyset (&s);
519 sigaddset (&s, sig);
520 // cppcheck-suppress uninitvar
521 return wait (&s, info, msecs) == sig;
522}
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: