40#if defined(__aarch64__) && defined(__linux)
76 return GetCurrentProcessId ();
87 PROCESS_BASIC_INFORMATION pbi;
88 if (NtQueryInformationProcess (GetCurrentProcess(),ProcessBasicInformation,
89 &pbi,
sizeof (pbi), 0) == STATUS_SUCCESS)
90 return pbi.InheritedFromUniqueProcessId;
155#if !HAVE_POSIX_SIGNALS || !SA_SIGINFO
178 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" 0x%08lx ", info.m_text_start));
179 MYWRITE (fd, info.m_filename, strlen (info.m_filename));
187SEHFatal (PEXCEPTION_POINTERS info)
189 Signal::fatal (SIGABRT, info->ExceptionRecord, info->ContextRecord);
190 return EXCEPTION_EXECUTE_HANDLER;
197#if !HAVE_POSIX_SIGNALS
204 assert (sig > 0 && sig < NSIG);
207 memset (&info, 0,
sizeof (info));
218 return strsignal (sig);
219#elif HAVE_SYS_SIGLIST
220 return sys_siglist [sig];
225 static char buf [NSIG] [buf_size];
227 snprintf (
buf [sig], buf_size,
"Signal %d", sig);
237 assert (sig > 0 && sig < NSIG);
240#if HAVE_POSIX_SIGNALS
241 struct sigaction old;
242 STDC::memset (&old, 0,
sizeof (old));
243 if (sigaction (sig, &old, 0) == 0)
278 assert (sig > 0 && sig < NSIG);
283#if !HAVE_POSIX_SIGNALS || !SA_SIGINFO
297#if HAVE_POSIX_SIGNALS
298 struct sigaction old, act;
299 STDC::memset (&act, 0,
sizeof (act));
300 STDC::memset (&old, 0,
sizeof (old));
301 act.sa_flags = SA_RESTART | SA_SIGINFO;
305 act.sa_mask = *blockMask;
306 else if (sigaction (sig, &old, 0) == 0)
307 act.sa_mask = old.sa_mask;
314 if (sigaction (sig, &act, &old) == -1)
339#if HAVE_POSIX_SIGNALS
354#if HAVE_POSIX_SIGNALS
356 sigprocmask (sense ? SIG_BLOCK : SIG_UNBLOCK,
mask, 0);
366#if HAVE_POSIX_SIGNALS
368 sigprocmask (SIG_SETMASK,
mask, old);
379 return ::raise (sig);
381 return ::kill (getpid (), sig);
400#if HAVE_POSIX_RT_SIGNALS
406 return sigqueue (
process, sig, v);
418#if HAVE_POSIX_RT_SIGNALS
424 return sigqueue (
process, sig, v);
437#if HAVE_POSIX_RT_SIGNALS
441 return queue (getpid (), sig, value);
454#if HAVE_POSIX_RT_SIGNALS
458 return queue (getpid (), sig, value);
474#if HAVE_POSIX_SIGNALS
490#if HAVE_POSIX_SIGNALS
520 return wait (&s, info, msecs) == sig;
534#if HAVE_POSIX_RT_SIGNALS
544 sigwaitinfo (
mask, &myinfo);
547 ts.tv_sec = msecs / 1000;
548 ts.tv_nsec = (msecs % 1000) * 1000000;
549 if (sigtimedwait (
mask, &myinfo, &
ts) == -1 && errno == EINTR)
557 return myinfo.si_signo;
582 static int hups [] = {
602 for (
unsigned sig = 0; hups [sig] != -1; ++sig)
603 handle (hups [sig], quit);
648 FatalReturn mainreturn ,
672 static const int hups [] = {
688 static int fatals [] = {
733 if (applicationName && *applicationName)
734 s_applicationName = applicationName;
758 s_fatalReturn = mainreturn;
761 s_fatalOptions = options;
765 assert (s_fatalReturn || (s_fatalOptions & FATAL_AUTO_EXIT));
768 if (options & FATAL_ON_QUIT)
769 for (
unsigned sig = 0; hups [sig] != -1; ++sig)
770 handle (hups [sig], fatal);
772 for (
unsigned sig = 0; fatals [sig] != -1; ++sig)
773 handle (fatals [sig], fatal);
777 if (options & FATAL_ON_INT)
778 handle (SIGINT, fatal);
783 if (options & USR1_DUMP_CORE)
788 SetUnhandledExceptionFilter (&SEHFatal);
821 if (! s_quitHook || (*s_quitHook) (sig, info,
x))
896 assert (s_fatalReturn || (s_fatalOptions & FATAL_AUTO_EXIT));
898#if !HAVE_POSIX_SIGNALS
902 handle (sig, &fatal);
923 bool fatal = (
sig != SIGINT) || (s_fatalOptions & FATAL_ON_INT);
928 bool haveCore =
false;
929 if (s_inFatal == 1 && fatal && (s_fatalOptions & FATAL_DUMP_CORE))
934 haveCore = (::stat (
"core", &st) == 0
935 && S_ISREG (
st.st_mode)
944 if (s_inFatal > 1 || (s_fatalOptions & FATAL_AUTO_EXIT))
947 ? (*s_fatalHook) (haveCore ? -sig : sig, info,
x)
948 : fatalDump (haveCore ? -sig : sig, info,
x))
969 static const struct {
int sig;
int code;
const char *desc; } infos [] = {
970#if HAVE_POSIX_SIGNALS
971 { -1, SI_USER,
"user sent: kill, sigsend or raise" },
973 { -1, SI_KERNEL,
"kernel" },
975 { -1, SI_QUEUE,
"sigqueue" },
976 { -1, SI_TIMER,
"timer expired" },
977 { -1, SI_MESGQ,
"mesq state changed" },
978 { -1, SI_ASYNCIO,
"AIO completed" },
980 { -1, SI_SIGIO,
"queued SIGIO" },
984 { SIGILL, ILL_NOOP,
"noop" },
986 { SIGILL, ILL_ILLOPC,
"illegal opcode" },
988 { SIGILL, ILL_ILLOPN,
"illegal operand" },
991 { SIGILL, ILL_ILLADR,
"illegal addressing mode" },
993 { SIGILL, ILL_ILLTRP,
"illegal trap" },
994 { SIGILL, ILL_PRVOPC,
"privileged opcode" },
996 { SIGILL, ILL_PRVREG,
"privileged register" },
999 { SIGILL, ILL_COPROC,
"coprocessor error" },
1002 { SIGILL, ILL_BADSTK,
"internal stack error" },
1006 { SIGFPE, FPE_NOOP,
"noop" },
1009 { SIGFPE, FPE_INTDIV,
"integer divide by zero" },
1012 { SIGFPE, FPE_INTOVF,
"integer overflow" },
1014 { SIGFPE, FPE_FLTDIV,
"floating point divide by zero" },
1015 { SIGFPE, FPE_FLTOVF,
"floating point overflow" },
1016 { SIGFPE, FPE_FLTUND,
"floating point underflow" },
1017 { SIGFPE, FPE_FLTRES,
"floating point inexact result" },
1018 { SIGFPE, FPE_FLTINV,
"floating point invalid operation" },
1020 { SIGFPE, FPE_FLTSUB,
"subscript out of range" },
1024 { SIGSEGV, SEGV_NOOP,
"noop" },
1026 { SIGSEGV, SEGV_MAPERR,
"address not mapped to object" },
1027 { SIGSEGV, SEGV_ACCERR,
"invalid permissions for mapped object" },
1030 { SIGBUS, BUS_NOOP,
"noop" },
1032 { SIGBUS, BUS_ADRALN,
"invalid address alignment" },
1034 { SIGBUS, BUS_ADRERR,
"non-existent physical address" },
1037 { SIGBUS, BUS_OBJERR,
"object specific hardware error" },
1041 { SIGTRAP, TRAP_BRKPT,
"process break point" },
1044 { SIGTRAP, TRAP_TRACE,
"process trace trap" },
1048 { SIGCHLD, CLD_NOOP,
"noop" },
1050 { SIGCHLD, CLD_EXITED,
"child has exited" },
1051 { SIGCHLD, CLD_KILLED,
"child was killed" },
1052 { SIGCHLD, CLD_DUMPED,
"child terminated abnormally" },
1053 { SIGCHLD, CLD_TRAPPED,
"traced child has trapped" },
1054 { SIGCHLD, CLD_STOPPED,
"child has stopped" },
1055 { SIGCHLD, CLD_CONTINUED,
"stopped child has continued" },
1058 { SIGPOLL, POLL_IN,
"data input available" },
1059 { SIGPOLL, POLL_OUT,
"output buffers available" },
1060 { SIGPOLL, POLL_MSG,
"input message available" },
1061 { SIGPOLL, POLL_ERR,
"i/o error" },
1062 { SIGPOLL, POLL_PRI,
"high priority input available" },
1063 { SIGPOLL, POLL_HUP,
"device disconnected" },
1070 for (
unsigned i = 0; infos [i].desc; ++i)
1071 if ((infos [i].sig == -1 || infos [i].sig == sig)
1072 && infos [i].code == code)
1073 return infos [i].desc;
1075 return "*unknown reason*";
1089# define DOCODE(x) case x: name = #x
1091 const char *
name = 0;
1093 switch (info->ExceptionCode)
1095 DOCODE(STATUS_ABANDONED_WAIT_0);
1096 DOCODE(STATUS_ACCESS_VIOLATION);
1097 DOCODE(STATUS_ARRAY_BOUNDS_EXCEEDED);
1098 DOCODE(STATUS_BREAKPOINT);
1099 DOCODE(STATUS_CONTROL_C_EXIT);
1100 DOCODE(STATUS_DATATYPE_MISALIGNMENT);
1101 DOCODE(STATUS_FLOAT_DENORMAL_OPERAND);
1102 DOCODE(STATUS_FLOAT_DIVIDE_BY_ZERO);
1103 DOCODE(STATUS_FLOAT_INEXACT_RESULT);
1104 DOCODE(STATUS_FLOAT_INVALID_OPERATION);
1105 DOCODE(STATUS_FLOAT_OVERFLOW);
1106 DOCODE(STATUS_FLOAT_STACK_CHECK);
1107 DOCODE(STATUS_FLOAT_UNDERFLOW);
1108 DOCODE(STATUS_GUARD_PAGE_VIOLATION);
1109 DOCODE(STATUS_ILLEGAL_INSTRUCTION);
1110 DOCODE(STATUS_INTEGER_DIVIDE_BY_ZERO);
1111 DOCODE(STATUS_INTEGER_OVERFLOW);
1112 DOCODE(STATUS_INVALID_DISPOSITION);
1113 DOCODE(STATUS_IN_PAGE_ERROR);
1114 DOCODE(STATUS_NONCONTINUABLE_EXCEPTION);
1115 DOCODE(STATUS_NO_MEMORY);
1116 DOCODE(STATUS_PENDING);
1117 DOCODE(STATUS_PRIVILEGED_INSTRUCTION);
1118 DOCODE(STATUS_SINGLE_STEP);
1119 DOCODE(STATUS_STACK_OVERFLOW);
1120 DOCODE(STATUS_TIMEOUT);
1121 DOCODE(STATUS_USER_APC);
1122 DOCODE(STATUS_WAIT_0);
1133 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
"Exception %lu\n",
1134 info->ExceptionCode));
1135 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" addr = %08lx", info->ExceptionAddress));
1137#elif HAVE_POSIX_SIGNALS
1140 " signo = %d, errno = %d, code = %d (%s)\n",
1141 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) {
1156 const long status = info->si_status;
1157 const long utime = info->si_utime;
1158 const long stime = info->si_stime;
1160 " status = %ld, utime = %ld, stime = %ld\n",
1161 status, utime,
stime));
1166 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" value = (%d, %p)\n",
1167 info->si_int, info->si_ptr));
1170 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS)
1172 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" addr = %p\n", info->si_addr));
1178 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" band = %ld, fd = %d\n",
1179 (
long) info->si_band, info->si_fd));
1191 for (
size_t i = 0; i < n; )
1193 size_t m = snprintf (
buf, buf_size,
"\n ");
1194 for (
size_t j = 0; i < n && j < 32; ++j, ++i)
1195 m += snprintf (
buf + m, buf_size-m,
"%s%02x",
1196 j % 4 == 0 ?
" " :
"",
1197 (
unsigned int) (((
const unsigned char *) data) [i]));
1212 unsigned long sp = 0;
1213#if defined _WIN32 && defined _M_IX86
1214 const CONTEXT *uc =
static_cast<const CONTEXT *
> (context);
1217 "\n eip: %04lx:%08lx eflags: %08lx"
1218 "\n eax: %08lx ebx: %08lx"
1219 " ecx: %08lx edx: %08lx"
1220 "\n esi: %08lx edi: %08lx"
1221 " ebp: %08lx esp: %08lx"
1222 "\n ds: %04lx es: %04lx"
1223 " fs: %04lx ss: %04lx",
1224 uc->SegCs, uc->Eip, uc->EFlags,
1225 uc->Eax, uc->Ebx, uc->Ecx, uc->Edx,
1226 uc->Esi, uc->Edi, uc->Ebp, uc->Esp,
1227 uc->SegDs, uc->SegEs, uc->SegFs, uc->SegSs));
1230 "\n FPU: control = %08lx"
1233 "\n ip = %04lx:%08lx"
1234 "\n data = %04lx:%08lx"
1236 uc->FloatSave.ControlWord,
1237 uc->FloatSave.StatusWord,
1238 uc->FloatSave.TagWord,
1239 uc->FloatSave.ErrorSelector,
1240 uc->FloatSave.ErrorOffset,
1241 uc->FloatSave.DataSelector,
1242 uc->FloatSave.DataOffset,
1243 uc->FloatSave.Cr0NpxState));
1245 for (
int i = 0; i < 8; ++i)
1247 "\n %%fp%d = [%02x%02x:%02x%02x%02x%02x"
1248 "%02x%02x%02x%02x]",
1250 uc->FloatSave.RegisterArea [i * 10 + 0],
1251 uc->FloatSave.RegisterArea [i * 10 + 1],
1252 uc->FloatSave.RegisterArea [i * 10 + 2],
1253 uc->FloatSave.RegisterArea [i * 10 + 3],
1254 uc->FloatSave.RegisterArea [i * 10 + 4],
1255 uc->FloatSave.RegisterArea [i * 10 + 5],
1256 uc->FloatSave.RegisterArea [i * 10 + 6],
1257 uc->FloatSave.RegisterArea [i * 10 + 7],
1258 uc->FloatSave.RegisterArea [i * 10 + 8],
1259 uc->FloatSave.RegisterArea [i * 10 + 9]));
1262#elif HAVE_POSIX_SIGNALS
1264 const ucontext_t *uc =
static_cast<const ucontext_t *
> (context);
1265 const mcontext_t *
mc = &uc->uc_mcontext;
1266 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
" stack = (%x, %x, %p)",
1267 uc->uc_stack.ss_flags,
1268 unsigned(uc->uc_stack.ss_size),
1269 uc->uc_stack.ss_sp));
1272#if defined __i386 && defined __linux
1273# if !defined REG_CS && defined CS
1289# define REG_UESP UESP
1290# define REG_TRAPNO TRAPNO
1293 sp =
mc->gregs[REG_ESP];
1295 "\n eip: %04x:%08x eflags: %08x"
1296 "\n eax: %08x ebx: %08x"
1297 " ecx: %08x edx: %08x"
1298 "\n esi: %08x edi: %08x"
1299 " ebp: %08x esp: %08x"
1300 "\n ds: %04x es: %04x"
1301 " fs: %04x ss: %04x",
1302 mc->gregs [REG_CS] & 0xffff,
mc->gregs [REG_EIP],
1303 mc->gregs [REG_EFL],
1304 mc->gregs [REG_EAX],
mc->gregs [REG_EBX],
1305 mc->gregs [REG_ECX],
mc->gregs [REG_EDX],
1306 mc->gregs [REG_ESI],
mc->gregs [REG_EDI],
1307 mc->gregs [REG_EBP],
mc->gregs [REG_ESP],
1308 mc->gregs [REG_DS] & 0xffff,
1309 mc->gregs [REG_ES] & 0xffff,
1310 mc->gregs [REG_FS] & 0xffff,
1311 mc->gregs [REG_SS] & 0xffff));
1314 "\n\n signal esp: %08x"
1316 " oldmask: %08lx cr2: %08lx",
1317 mc->gregs [REG_UESP],
1318 mc->gregs [REG_TRAPNO],
mc->gregs [REG_ERR],
1319 mc->oldmask,
mc->cr2));
1325 "\n FPU: control = %08lx"
1328 "\n ip = %04lx:%08lx"
1329 "\n data = %04lx:%08lx"
1331 mc->fpregs->cw,
mc->fpregs->sw,
mc->fpregs->tag,
1332 mc->fpregs->cssel & 0xffff,
mc->fpregs->ipoff,
1333 mc->fpregs->datasel & 0xffff,
mc->fpregs->dataoff,
1334 mc->fpregs->status));
1336 for (
int i = 0; i < 8; ++i)
1338 "\n %%fp%d = [%04hx:%04hx%04hx%04hx%04hx]",
1340 mc->fpregs->_st [i].exponent,
1341 mc->fpregs->_st [i].significand [0],
1342 mc->fpregs->_st [i].significand [1],
1343 mc->fpregs->_st [i].significand [2],
1344 mc->fpregs->_st [i].significand [3]));
1347#elif defined __x86_64__ && defined __linux
1348 sp =
mc->gregs[REG_RSP];
1350 "\n rip: %04x:%016llx eflags: %016llx"
1351 "\n rax: %016llx rbx: %016llx"
1352 "\n rcx: %016llx rdx: %016llx"
1353 "\n r08: %016llx r09: %016llx"
1354 "\n r10: %016llx r11: %016llx"
1355 "\n r12: %016llx r13: %016llx"
1356 "\n r14: %016llx r15: %016llx"
1357 "\n rsi: %016llx rdi: %016llx"
1358 "\n rbp: %016llx rsp: %016llx"
1359 "\n gs: %04x fs: %04x",
1360 (
unsigned)
mc->gregs [REG_CSGSFS] & 0xffff,
1361 (
unsigned long long)
mc->gregs [REG_RIP],
1362 (
unsigned long long)
mc->gregs [REG_EFL],
1363 (
unsigned long long)
mc->gregs [REG_RAX],
1364 (
unsigned long long)
mc->gregs [REG_RBX],
1365 (
unsigned long long)
mc->gregs [REG_RCX],
1366 (
unsigned long long)
mc->gregs [REG_RDX],
1367 (
unsigned long long)
mc->gregs [REG_R8],
1368 (
unsigned long long)
mc->gregs [REG_R9],
1369 (
unsigned long long)
mc->gregs [REG_R10],
1370 (
unsigned long long)
mc->gregs [REG_R11],
1371 (
unsigned long long)
mc->gregs [REG_R12],
1372 (
unsigned long long)
mc->gregs [REG_R13],
1373 (
unsigned long long)
mc->gregs [REG_R14],
1374 (
unsigned long long)
mc->gregs [REG_R15],
1375 (
unsigned long long)
mc->gregs [REG_RSI],
1376 (
unsigned long long)
mc->gregs [REG_RDI],
1377 (
unsigned long long)
mc->gregs [REG_RBP],
1378 (
unsigned long long)
mc->gregs [REG_RSP],
1379 (
unsigned)(
mc->gregs [REG_CSGSFS]>>16) & 0xffff,
1380 (
unsigned)(
mc->gregs [REG_CSGSFS]>>32) & 0xffff));
1385 " oldmask: %16llx cr2: %016llx",
1386 (
unsigned long long)
mc->gregs [REG_TRAPNO],
1387 (
unsigned long long)
mc->gregs [REG_ERR],
1388 (
unsigned long long)
mc->gregs [REG_OLDMASK],
1389 (
unsigned long long)
mc->gregs [REG_CR2]));
1395 "\n FPU: control = %04x"
1402 "\n mxcr_mask= %08x",
1410 mc->fpregs->mxcr_mask));
1412 for (
int i = 0; i < 8; ++i)
1414 "\n %%fp%d = [%04hx:%04hx%04hx%04hx%04hx]",
1416 mc->fpregs->_st [i].exponent,
1417 mc->fpregs->_st [i].significand [0],
1418 mc->fpregs->_st [i].significand [1],
1419 mc->fpregs->_st [i].significand [2],
1420 mc->fpregs->_st [i].significand [3]));
1422 for (
int i = 0; i < 16; ++i)
1424 "\n %%xmm%02d = [%08x %08x %08x %08x]",
1426 mc->fpregs->_xmm[i].element[0],
1427 mc->fpregs->_xmm[i].element[1],
1428 mc->fpregs->_xmm[i].element[2],
1429 mc->fpregs->_xmm[i].element[3]));
1432#elif __APPLE__ && defined __ppc__
1433 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
"\n dar: %08lx dsisr: %08lx exception: %08lx",
1434 (*mc)->es.dar, (*mc)->es.dsisr, (*mc)->es.exception));
1437 "\n srr0: %08x srr1: %08x cr: %08x xer: %08x"
1438 "\n lr: %08x ctr: %08x vrsave: %08x fpscr: %08x",
1439 (*mc)->ss.srr0, (*mc)->ss.srr1, (*mc)->ss.cr, (*mc)->ss.xer,
1440 (*mc)->ss.lr, (*mc)->ss.ctr, (*mc)->ss.vrsave, (*mc)->fs.fpscr));
1442 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
"\n vrvalid: %08x vscr: %08lx:%08lx:%08lx:%08lx\n",
1443 (*mc)->vs.save_vrvalid,
1444 (*mc)->vs.save_vscr [0], (*mc)->vs.save_vscr [1],
1445 (*mc)->vs.save_vscr [2], (*mc)->vs.save_vscr [3]));
1447 for (
unsigned int *regs = &(*mc)->ss.r0, i = 0; i < 32; i += 4)
1448 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
"\n r%-2d %08x r%-2d %08x r%-2d %08x r%-2d %08x",
1449 i, regs [i], i+1, regs [i+1], i+2, regs [i+2], i+3, regs [i+3]));
1450 for (
int i = 0; i < 32; ++i)
1451 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
"\n fp%-2d %016qx (%f)", i,
1452 *(
unsigned long long *) &(*mc)->fs.fpregs [i],
1453 (*mc)->fs.fpregs [i]));
1454 for (
int i = 0; i < 32; ++i)
1455 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
"\n vr%-2d %08lx:%08lx:%08lx:%08lx", i,
1456 (*mc)->vs.save_vr[i][0], (*mc)->vs.save_vr[i][1],
1457 (*mc)->vs.save_vr[i][2], (*mc)->vs.save_vr[i][3]));
1458#elif defined __aarch64__ && defined __linux
1459 CxxUtils::aarch64_dump_registers (fd,
buf, buf_size, *
mc);
1461 for (
int i = 0; i < NGREG; i++)
1462 MYWRITE (fd,
buf, snprintf (
buf, buf_size,
"%s %%r%02d = %08x",
1463 i % 4 == 0 ?
"\n" :
"", i,
mc->gregs [i]));
1516 return fatalDump (sig, info, extra, s_fatalFd, s_fatalOptions);
1523 const unsigned int buf_size =
sizeof (
buf);
1524 bool haveCore =
false;
1531 if (options & FATAL_DUMP_SIG)
1534 if (s_applicationName)
1536 MYWRITE (fd, s_applicationName,
1537 STDC::strlen (s_applicationName));
1545 sig, name (sig), haveCore ?
" (core dumped)" :
""));
1547 MYWRITE (fd,
buf, snprintf(
buf, buf_size,
"signal context:\n"));
1548 dumpInfo (fd,
buf, buf_size, sig, info);
1551 unsigned long sp = 0;
1552 if (options & FATAL_DUMP_CONTEXT)
1553 sp = dumpContext (fd,
buf, buf_size, extra);
1555 if (options & FATAL_DUMP_STACK)
1557 MYWRITE (fd,
buf, snprintf(
buf, buf_size,
"\nstack trace:\n"));
1559 MYWRITE (fd,
buf, snprintf(
buf, buf_size,
"\n(backtrace failed; raw dump follows)\n"));
1560 MYWRITE (fd,
buf, snprintf(
buf, buf_size,
"%016lx:", s_lastSP.load()));
1561 dumpMemory (fd,
buf, buf_size,
reinterpret_cast<void*
>(s_lastSP.load()), 1024);
1566 DebugAids::stacktrace (fd);
1571 if (options & FATAL_DUMP_LIBS)
1573 MYWRITE (fd,
buf, snprintf(
buf, buf_size,
"\nshared libraries present:\n"));
1597{
return s_fatalHook; }
1603{
return s_fatalReturn; }
1609{
return s_fatalOptions; }
1615{
return s_quitHook; }
1627{
return s_inFatal; }
1634{
return s_crashed; }
1645 Athena::Signal::handleFatal(
nullptr, 1);
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)
Callback1Rep< T1 > * CreateCallback(void(*function)(T1, T2), const T2 &fill_2)
static pid_t ProcessInfo__pid(void)
Get the process id.
void CxxUtils_installFatalHandler ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options. This is meant to be easy to call from python via ctypes.
static const int SIGNAL_MESSAGE_BUFSIZE
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 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.
static void coredump(int sig,...)
Drop a core dump and continue.
Callback1< const LibraryInfo & > InfoHandler
static void loaded(InfoHandler &handler)
Iterate and provide information about all currently loaded shared libraries.
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.
Information about a currently loaded shared library.