41#if defined(__aarch64__) && defined(__linux)
77 return GetCurrentProcessId ();
88 PROCESS_BASIC_INFORMATION pbi;
89 if (NtQueryInformationProcess (GetCurrentProcess(),ProcessBasicInformation,
90 &pbi,
sizeof (pbi), 0) == STATUS_SUCCESS)
91 return pbi.InheritedFromUniqueProcessId;
156#if !HAVE_POSIX_SIGNALS || !SA_SIGINFO
179 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" 0x%08lx ", info.m_text_start));
180 MYWRITE (fd, info.m_filename, strlen (info.m_filename));
188SEHFatal (PEXCEPTION_POINTERS info)
190 Signal::fatal (SIGABRT, info->ExceptionRecord, info->ContextRecord);
191 return EXCEPTION_EXECUTE_HANDLER;
198#if !HAVE_POSIX_SIGNALS
205 assert (sig > 0 && sig < NSIG);
208 memset (&info, 0,
sizeof (info));
219 return strsignal (sig);
220#elif HAVE_SYS_SIGLIST
221 return sys_siglist [sig];
226 static char buf [NSIG] [buf_size];
228 snprintf (
buf [sig], buf_size,
"Signal %d", sig);
238 assert (sig > 0 && sig < NSIG);
241#if HAVE_POSIX_SIGNALS
242 struct sigaction old;
243 STDC::memset (&old, 0,
sizeof (old));
244 if (sigaction (sig, &old, 0) == 0)
279 assert (sig > 0 && sig < NSIG);
284#if !HAVE_POSIX_SIGNALS || !SA_SIGINFO
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;
306 act.sa_mask = *blockMask;
307 else if (sigaction (sig, &old, 0) == 0)
308 act.sa_mask = old.sa_mask;
315 if (sigaction (sig, &act, &old) == -1)
340#if HAVE_POSIX_SIGNALS
355#if HAVE_POSIX_SIGNALS
357 sigprocmask (sense ? SIG_BLOCK : SIG_UNBLOCK,
mask, 0);
367#if HAVE_POSIX_SIGNALS
369 sigprocmask (SIG_SETMASK,
mask, old);
380 return ::raise (sig);
382 return ::kill (getpid (), sig);
401#if HAVE_POSIX_RT_SIGNALS
407 return sigqueue (
process, sig, v);
419#if HAVE_POSIX_RT_SIGNALS
425 return sigqueue (
process, sig, v);
438#if HAVE_POSIX_RT_SIGNALS
442 return queue (getpid (), sig, value);
455#if HAVE_POSIX_RT_SIGNALS
459 return queue (getpid (), sig, value);
475#if HAVE_POSIX_SIGNALS
491#if HAVE_POSIX_SIGNALS
521 return wait (&s, info, msecs) == sig;
535#if HAVE_POSIX_RT_SIGNALS
545 sigwaitinfo (
mask, &myinfo);
548 ts.tv_sec = msecs / 1000;
549 ts.tv_nsec = (msecs % 1000) * 1000000;
550 if (sigtimedwait (
mask, &myinfo, &
ts) == -1 && errno == EINTR)
558 return myinfo.si_signo;
583 static int hups [] = {
603 for (
unsigned sig = 0; hups [sig] != -1; ++sig)
604 handle (hups [sig], quit);
649 FatalReturn mainreturn ,
673 static const int hups [] = {
689 static int fatals [] = {
734 if (applicationName && *applicationName)
735 s_applicationName = applicationName;
759 s_fatalReturn = mainreturn;
762 s_fatalOptions = options;
766 assert (s_fatalReturn || (s_fatalOptions & FATAL_AUTO_EXIT));
769 if (options & FATAL_ON_QUIT)
770 for (
unsigned sig = 0; hups [sig] != -1; ++sig)
771 handle (hups [sig], fatal);
773 for (
unsigned sig = 0; fatals [sig] != -1; ++sig)
774 handle (fatals [sig], fatal);
778 if (options & FATAL_ON_INT)
779 handle (SIGINT, fatal);
784 if (options & USR1_DUMP_CORE)
789 SetUnhandledExceptionFilter (&SEHFatal);
822 if (! s_quitHook || (*s_quitHook) (sig, info,
x))
897 assert (s_fatalReturn || (s_fatalOptions & FATAL_AUTO_EXIT));
899#if !HAVE_POSIX_SIGNALS
903 handle (sig, &fatal);
924 bool fatal = (
sig != SIGINT) || (s_fatalOptions & FATAL_ON_INT);
929 bool haveCore =
false;
930 if (s_inFatal == 1 && fatal && (s_fatalOptions & FATAL_DUMP_CORE))
935 haveCore = (::stat (
"core", &st) == 0
936 && S_ISREG (
st.st_mode)
945 if (s_inFatal > 1 || (s_fatalOptions & FATAL_AUTO_EXIT))
948 ? (*s_fatalHook) (haveCore ? -sig : sig, info,
x)
949 : fatalDump (haveCore ? -sig : sig, info,
x))
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" },
974 { -1, SI_KERNEL,
"kernel" },
976 { -1, SI_QUEUE,
"sigqueue" },
977 { -1, SI_TIMER,
"timer expired" },
978 { -1, SI_MESGQ,
"mesq state changed" },
979 { -1, SI_ASYNCIO,
"AIO completed" },
981 { -1, SI_SIGIO,
"queued SIGIO" },
985 { SIGILL, ILL_NOOP,
"noop" },
987 { SIGILL, ILL_ILLOPC,
"illegal opcode" },
989 { SIGILL, ILL_ILLOPN,
"illegal operand" },
992 { SIGILL, ILL_ILLADR,
"illegal addressing mode" },
994 { SIGILL, ILL_ILLTRP,
"illegal trap" },
995 { SIGILL, ILL_PRVOPC,
"privileged opcode" },
997 { SIGILL, ILL_PRVREG,
"privileged register" },
1000 { SIGILL, ILL_COPROC,
"coprocessor error" },
1003 { SIGILL, ILL_BADSTK,
"internal stack error" },
1007 { SIGFPE, FPE_NOOP,
"noop" },
1010 { SIGFPE, FPE_INTDIV,
"integer divide by zero" },
1013 { SIGFPE, FPE_INTOVF,
"integer overflow" },
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" },
1021 { SIGFPE, FPE_FLTSUB,
"subscript out of range" },
1025 { SIGSEGV, SEGV_NOOP,
"noop" },
1027 { SIGSEGV, SEGV_MAPERR,
"address not mapped to object" },
1028 { SIGSEGV, SEGV_ACCERR,
"invalid permissions for mapped object" },
1031 { SIGBUS, BUS_NOOP,
"noop" },
1033 { SIGBUS, BUS_ADRALN,
"invalid address alignment" },
1035 { SIGBUS, BUS_ADRERR,
"non-existent physical address" },
1038 { SIGBUS, BUS_OBJERR,
"object specific hardware error" },
1042 { SIGTRAP, TRAP_BRKPT,
"process break point" },
1045 { SIGTRAP, TRAP_TRACE,
"process trace trap" },
1049 { SIGCHLD, CLD_NOOP,
"noop" },
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" },
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" },
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;
1076 return "*unknown reason*";
1090# define DOCODE(x) case x: name = #x
1092 const char *
name = 0;
1094 switch (info->ExceptionCode)
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);
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));
1138#elif HAVE_POSIX_SIGNALS
1141 " signo = %d, errno = %d, code = %d (%s)\n",
1142 info->si_signo, info->si_errno, info->si_code,
1147 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" pid = %ld, uid = %ld\n",
1148 (
long) info->si_pid, (
long) info->si_uid));
1151 if (sig == SIGCHLD) {
1155 const long status = info->si_status;
1156 const long utime = info->si_utime;
1157 const long stime = info->si_stime;
1159 " status = %ld, utime = %ld, stime = %ld\n",
1160 status, utime,
stime));
1164 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" value = (%d, %p)\n",
1165 info->si_int, info->si_ptr));
1168 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS)
1169 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" addr = %p\n", info->si_addr));
1174 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" band = %ld, fd = %d\n",
1175 (
long) info->si_band, info->si_fd));
1187 for (
size_t i = 0; i < n; )
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]));
1208 unsigned long sp = 0;
1209#if defined _WIN32 && defined _M_IX86
1210 const CONTEXT *uc =
static_cast<const CONTEXT *
> (context);
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));
1226 "\n FPU: control = %08lx"
1229 "\n ip = %04lx:%08lx"
1230 "\n data = %04lx:%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));
1241 for (
int i = 0; i < 8; ++i)
1243 "\n %%fp%d = [%02x%02x:%02x%02x%02x%02x"
1244 "%02x%02x%02x%02x]",
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]));
1258#elif HAVE_POSIX_SIGNALS
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));
1268#if defined __i386 && defined __linux
1269# if !defined REG_CS && defined CS
1285# define REG_UESP UESP
1286# define REG_TRAPNO TRAPNO
1289 sp =
mc->gregs[REG_ESP];
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));
1310 "\n\n signal esp: %08x"
1312 " oldmask: %08lx cr2: %08lx",
1313 mc->gregs [REG_UESP],
1314 mc->gregs [REG_TRAPNO],
mc->gregs [REG_ERR],
1315 mc->oldmask,
mc->cr2));
1321 "\n FPU: control = %08lx"
1324 "\n ip = %04lx:%08lx"
1325 "\n data = %04lx:%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));
1332 for (
int i = 0; i < 8; ++i)
1334 "\n %%fp%d = [%04hx:%04hx%04hx%04hx%04hx]",
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]));
1343#elif defined __x86_64__ && defined __linux
1344 sp =
mc->gregs[REG_RSP];
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));
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]));
1391 "\n FPU: control = %04x"
1398 "\n mxcr_mask= %08x",
1406 mc->fpregs->mxcr_mask));
1408 for (
int i = 0; i < 8; ++i)
1410 "\n %%fp%d = [%04hx:%04hx%04hx%04hx%04hx]",
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]));
1418 for (
int i = 0; i < 16; ++i)
1420 "\n %%xmm%02d = [%08x %08x %08x %08x]",
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]));
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));
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));
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]));
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);
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]));
1512 return fatalDump (sig, info, extra, s_fatalFd, s_fatalOptions);
1519 const unsigned int buf_size =
sizeof (
buf);
1520 bool haveCore =
false;
1527 if (options & FATAL_DUMP_SIG)
1530 if (s_applicationName)
1532 MYWRITE (fd, s_applicationName,
1533 STDC::strlen (s_applicationName));
1541 sig, name (sig), haveCore ?
" (core dumped)" :
""));
1543 MYWRITE (fd,
buf, snprintf(
buf, buf_size,
"signal context:\n"));
1544 dumpInfo (fd,
buf, buf_size, sig, info);
1547 unsigned long sp = 0;
1548 if (options & FATAL_DUMP_CONTEXT)
1549 sp = dumpContext (fd,
buf, buf_size, extra);
1551 if (options & FATAL_DUMP_STACK)
1553 MYWRITE (fd,
buf, snprintf(
buf, buf_size,
"\nstack trace:\n"));
1555 MYWRITE (fd,
buf, snprintf(
buf, buf_size,
"\n(backtrace failed; raw dump follows)\n"));
1556 MYWRITE (fd,
buf, snprintf(
buf, buf_size,
"%016lx:", s_lastSP.load()));
1557 dumpMemory (fd,
buf, buf_size,
reinterpret_cast<void*
>(s_lastSP.load()), 1024);
1562 DebugAids::stacktrace (fd);
1567 if (options & FATAL_DUMP_LIBS)
1569 MYWRITE (fd,
buf, snprintf(
buf, buf_size,
"\nshared libraries present:\n"));
1593{
return s_fatalHook; }
1599{
return s_fatalReturn; }
1605{
return s_fatalOptions; }
1611{
return s_quitHook; }
1623{
return s_inFatal; }
1630{
return s_crashed; }
1641 Athena::Signal::handleFatal(
nullptr, 1);
char data[hepevt_bytes_allocation_ATLAS]
Collecting a few shared bits and pieces from SEAL headers.
#define IOFD_INVALID
Invalid channel descriptor constant.
int IOFD
Type the system uses for channel descriptors.
This are the SEAL debug aids, adapted to build in Atlas, after the drop of that project.
#define MYWRITE(fd, data, n)
static pid_t ProcessInfo__pid(void)
Get the process id.
void CxxUtils_installFatalHandler ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
static const int SIGNAL_MESSAGE_BUFSIZE
Maximum length of a signal message.
static pid_t ProcessInfo__ppid(void)
Get the parent process id.
This is the signal handler from SEAL, adapted to build in Atlas, after the drop of that project.
#define sigismember(x, y)
static void coredump(int sig,...)
Drop a core dump and continue.
static void loaded(InfoHandler &handler)
Iterate and provide information about all currently loaded shared libraries.
Callback1< const LibraryInfo & > InfoHandler
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 unsigned s_fatalOptions
The current fatal signal handling options.
static int raise(int sig)
Raise the signal number sig.
bool(* QuitHook)(int sig, siginfo_t *info, void *x)
Application clean-up hook invoked before quit(int , siginfo_t *, void *) exits from program terminati...
static const char * name(int sig)
Return the name of the signal number sig.
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 paramet...
static void suspend(const sigset_t *mask)
Temporarily replace the signal mask of the process with mask and then suspend until a signal is recei...
static int kill(pid_t process, int sig)
Send the signal sig to process identified by process.
static IOFD s_fatalFd
The output file descriptor for fataldump().
static int queue(int sig, int value=0)
Queue signal sig for this process with additional data value.
static const char * describe(int sig, int code)
Return the description for signal info code code for signal number sig.
static FatalReturn s_fatalReturn
The application main return hook for fatal signals.
bool(* FatalHook)(int sig, siginfo_t *info, void *x)
Application hook to run in fatal().
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 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 const char * s_applicationName
The current application name.
static int s_inFatal
Indicator that we are currently executing inside fatal().
static bool wait(int sig, siginfo_t *info=0, long msecs=-1)
Suspend the thread waiting for signal sig at most msecs milliseconds.
static void block(int sig, bool sense)
Block or unblock the signal number sig.
static FatalHook s_fatalHook
The application handler hook for fatal signals.
static std::atomic< unsigned long > s_lastSP
Used to switch to a raw stack dump if we crash during a backtrace.
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 ...
static void ignore(int sig)
Ignore the signal number sig.
static void revert(int sig)
Revert the signal number sig back to its default behaviour.
static bool s_crashed
Indicator that the application has been crashed: that a fatal signal has been delivered.
static bool pending(int sig)
Check if sig is pending for this process.
static QuitHook s_quitHook
The application handler hook for quitting-related signals.
static void trampoline(int sig)
Internal signal handler trampoline to convert handler arguments to look more like POSIX signals.
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.
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 HandlerType s_trampolines[NSIG]
Actual signal handlers when POSIX signals are not available.
void(* HandlerType)(int sig, siginfo_t *info, void *extra)
Signal handler type.
std::string stime()
return the current data and time
const std::string process
Some weak symbol referencing magic... These are declared in AthenaKernel/getMessageSvc....
static void SignalDumpLibs(const SharedLibrary::LibraryInfo &info, IOFD fd)
Internal Signal::fataldump() dumper to produce the list of currently loaded shared libraries.
static SharedLibrary::InfoHandler * SignalDumpCallback
Shared library dump callback for Signal::fataldump().
static char buf[SIGNAL_MESSAGE_BUFSIZE]
Dump application state information on a fatal signal.
StatusCode ROOTMessageFilterSvc::initialize ATLAS_NOT_THREAD_SAFE()
Return the file descriptor fataldump() uses for output.
void(* DummyHandlerType)(int)
Dummy handler type for standard signal() function.
Callback1Rep< T1 > * CreateCallback(void(*function)(T1, T2), const T2 &fill_2)
Information about a currently loaded shared library.