ATLAS Offline Software
Public Types | Static Public Member Functions | Static Public Attributes | Static Private Member Functions | Static Private Attributes | List of all members
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). More...
 
typedef bool(* FatalHook) (int sig, siginfo_t *info, void *x)
 Application hook to run in fatal(). More...
 
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. More...
 
typedef void(* HandlerType) (int sig, siginfo_t *info, void *extra)
 Signal handler type. More...
 

Static Public Member Functions

static const char * name (int sig)
 Return the name of the signal number sig. More...
 
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). More...
 
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. More...
 
static void revert (int sig)
 Revert the signal number sig back to its default behaviour. More...
 
static void ignore (int sig)
 Ignore the signal number sig. More...
 
static void block (int sig, bool sense)
 Block or unblock the signal number sig. More...
 
static void block (const sigset_t *mask, bool sense)
 Block or unblock the signals specified by mask. More...
 
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). More...
 
static int raise (int sig)
 Raise the signal number sig. More...
 
static int kill (pid_t process, int sig)
 Send the signal sig to process identified by process. More...
 
static int queue (int sig, int value=0)
 Queue signal sig for this process with additional data value. More...
 
static int queue (int sig, void *value)
 Queue signal sig for this process with additional data value. More...
 
static int queue (pid_t process, int sig, int value=0)
 Queue signal sig with additional data value for process. More...
 
static int queue (pid_t process, int sig, void *value)
 Queue signal sig with additional data value for process. More...
 
static bool pending (int sig)
 Check if sig is pending for this process. More...
 
static void pending (sigset_t *mask)
 Return in mask the list of signals pending for this process. More...
 
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. More...
 
static bool wait (int sig, siginfo_t *info=0, long msecs=-1)
 Suspend the thread waiting for signal sig at most msecs milliseconds. More...
 
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. More...
 
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(). More...
 
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. More...
 
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(). More...
 
static const char * describe (int sig, int code)
 Return the description for signal info code code for signal number sig. More...
 

Static Public Attributes

static const int USR1_DUMP_CORE = 1
 Option that instructs #fatal(int, siginfo_t *, void *) to call #coredump() on SIGUSR1. More...
 
static const int FATAL_ON_QUIT = 2
 Option to make SIGHUP, SIGTERM and SIGQUIT fatal instead of just #quit(int , siginfo_t *, void *) signals. More...
 
static const int FATAL_ON_INT = 4
 Option to make SIGINT fatal. More...
 
static const int FATAL_DUMP_CORE = 8
 Option to make #fatal(int, siginfo_t *, void *) dump a core file before crashing. More...
 
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()). More...
 
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. More...
 
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. More...
 
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. More...
 
static const int FATAL_AUTO_EXIT = 256
 Option to make #fatal(int, siginfo_t *, void *) exit via #quit(int , siginfo_t *, void *). More...
 
static const int FATAL_DEFAULT
 Default options to #handleFatal(const char *, IOFD fd, FatalHook, FatalReturn, unsigned. More...
 

Static Private Member Functions

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

Static Private Attributes

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

Detailed Description

Utilities for handling signals and fatal errors.

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

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]

static 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]

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

◆ ATLAS_NOT_THREAD_SAFE() [3/13]

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

◆ ATLAS_NOT_THREAD_SAFE() [4/13]

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

◆ ATLAS_NOT_THREAD_SAFE() [5/13]

static 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]

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

◆ ATLAS_NOT_THREAD_SAFE() [7/13]

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

◆ ATLAS_NOT_THREAD_SAFE() [8/13]

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

◆ ATLAS_NOT_THREAD_SAFE() [9/13]

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

◆ ATLAS_NOT_THREAD_SAFE() [10/13]

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

◆ ATLAS_NOT_THREAD_SAFE() [11/13]

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

◆ ATLAS_NOT_THREAD_SAFE() [12/13]

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

◆ ATLAS_NOT_THREAD_SAFE() [13/13]

static 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 }

◆ 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
342  sigset_t mask;
343  sigemptyset (&mask);
344  sigaddset (&mask, sig);
345  block (&mask, sense);
346 #endif
347 }

◆ 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 }

◆ 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 }

◆ 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 }

◆ 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
320 #endif // HAVE_POSIX_SIGNALS
321  return oldhandler;
322 }

◆ 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);
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); }

◆ 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 }

◆ 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); }

◆ 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 }

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:

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:
grepfile.info
info
Definition: grepfile.py:38
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
Athena::Signal::FATAL_DUMP_STACK
static const int FATAL_DUMP_STACK
Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *,...
Definition: SealSignal.h:130
siginfo_t
Definition: SealSignal.h:77
Athena::Signal::FATAL_DUMP_CORE
static const int FATAL_DUMP_CORE
Option to make #fatal(int, siginfo_t *, void *) dump a core file before crashing.
Definition: SealSignal.h:122
Athena::BitTraits::Digits
@ Digits
Definition: SealDebug.h:63
Athena::Signal::dumpMemory
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.
Definition: SealSignal.cxx:1185
stime
std::string stime()
return the current data and time
Definition: computils.cxx:213
Athena::Signal::handler
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).
Definition: SealSignal.cxx:236
SUSY_SimplifiedModel_PostInclude.process
string process
Definition: SUSY_SimplifiedModel_PostInclude.py:42
Athena::Signal::FATAL_ON_INT
static const int FATAL_ON_INT
Option to make SIGINT fatal.
Definition: SealSignal.h:119
sigaddset
#define sigaddset(x, y)
Definition: SealSignal.h:84
Athena::Signal::USR1_DUMP_CORE
static const int USR1_DUMP_CORE
Option that instructs #fatal(int, siginfo_t *, void *) to call #coredump() on SIGUSR1.
Definition: SealSignal.h:111
sigset_t
int sigset_t
Definition: SealSignal.h:80
Athena::Signal::FATAL_DUMP_SIG
static const int FATAL_DUMP_SIG
Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *,...
Definition: SealSignal.h:126
mc
Definition: mc.PG_single_nu_valid.py:1
CaloCondBlobAlgs_fillNoiseFromASCII.desc
desc
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:54
Athena::Signal::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).
Definition: SealSignal.cxx:365
lumiFormat.i
int i
Definition: lumiFormat.py:92
sigismember
#define sigismember(x, y)
Definition: SealSignal.h:86
Athena::Signal::wait
static bool wait(int sig, siginfo_t *info=0, long msecs=-1)
Suspend the thread waiting for signal sig at most msecs milliseconds.
Definition: SealSignal.cxx:515
beamspotman.n
n
Definition: beamspotman.py:731
python.BuildSignatureFlags.sig
sig
Definition: BuildSignatureFlags.py:215
Athena::Signal::HandlerType
void(* HandlerType)(int sig, siginfo_t *info, void *extra)
Signal handler type.
Definition: SealSignal.h:196
Athena::Signal::FATAL_DUMP_LIBS
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
Athena::Signal::FATAL_DUMP_CONTEXT
static const int FATAL_DUMP_CONTEXT
Option to make #fataldump(int, siginfo_t *, void *) (invoked by #fatal(int, siginfo_t *,...
Definition: SealSignal.h:138
Athena::Signal::name
static const char * name(int sig)
Return the name of the signal number sig.
Definition: SealSignal.cxx:216
Athena::Signal::FATAL_AUTO_EXIT
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
ReadFromCoolCompare.fd
fd
Definition: ReadFromCoolCompare.py:196
pmontree.code
code
Definition: pmontree.py:443
Cut::signal
@ signal
Definition: SUSYToolsAlg.cxx:64
Athena::Signal::trampoline
static void trampoline(int sig)
Internal signal handler trampoline to convert handler arguments to look more like POSIX signals.
Definition: SealSignal.cxx:203
Athena::Signal::block
static void block(int sig, bool sense)
Block or unblock the signal number sig.
Definition: SealSignal.cxx:338
Athena::Signal::describe
static const char * describe(int sig, int code)
Return the description for signal info code code for signal number sig.
Definition: SealSignal.cxx:968
CSV_InDetExporter.old
old
Definition: CSV_InDetExporter.py:145
Athena::Signal::handle
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.
Definition: SealSignal.cxx:277
merge.status
status
Definition: merge.py:17
Athena::Signal::pending
static bool pending(int sig)
Check if sig is pending for this process.
Definition: SealSignal.cxx:471
Athena::Signal::s_trampolines
static HandlerType s_trampolines[NSIG]
Actual signal handlers when POSIX signals are not available.
Definition: SealSignal.h:283
sigemptyset
#define sigemptyset(x)
Definition: SealSignal.h:82
Athena::DummyHandlerType
void(* DummyHandlerType)(int)
Dummy handler type for standard signal() function.
Definition: SealSignal.cxx:109
MYWRITE
#define MYWRITE(fd, data, n)
Definition: SealDebug.h:44