static void trapILL(int sig RECARG) { static const char *emsg[] = { /* FPE_NOOP 0*/ "SIGILL", /* ILL_ILLOPC 1*/ "illegal opcode", /* ILL_ILLTRP 2*/ "illegal trap", /* ILL_PRVOPC 3*/ "privileged opcode", /* ILL_ILLOPN 4*/ "illegal operand", /* 5 */ "illegal addressing mode", /* 6 */ "privileged register", /* 7 */ "coprocessor error", /* 8 */ "internal stack error"}; CTX ctx = knh_getCurrentContext(); record_signal(ctx, sig RECDATA); if(ctx != NULL) { #if defined(K_USING_MINGW_) int si_code = 0; #else int si_code = (si->si_code < 9) ? si->si_code : 0; #endif /* defined(K_USING_MINGW_) */ WCTX(ctx)->signal = sig; THROW_Halt(ctx, NULL, emsg[si_code]); } _Exit(EX_SOFTWARE); }
static void trapBUS(int sig RECARG) { static const char *emsg[] = { /* BUS_NOOP 0*/ "BUS_NOOP", /* BUS_ADRALN 1*/ "invalid address alignment", /* BUS_ADRERR 2*/ "nonexistent physical address", /* BUS_OBJERR 3*/ "object-specific HW error"}; CTX ctx = knh_getCurrentContext(); record_signal(ctx, sig RECDATA); if(ctx != NULL) { int si_code = (si->si_code < 4) ? si->si_code : 1; WCTX(ctx)->signal = sig; THROW_Halt(ctx, NULL, emsg[si_code]); } _Exit(EX_SOFTWARE); }
static void trapSEGV(int sig RECARG) { CTX ctx = knh_getCurrentContext(); record_signal(ctx, sig RECDATA); #if !defined(K_USING_MINGW_) if (si->si_code == SEGV_ACCERR) { void* address = (void*)si->si_addr; fprintf(stderr, "address=%p\n", address); } #endif /* defined(K_USING_MINGW_) */ if(ctx != NULL) { WCTX(ctx)->signal = sig; THROW_Halt(ctx, NULL, "segmentation fault"); } _Exit(EX_SOFTWARE); }
void sig_handler(int sig) { static int64_t prev= 0; int64_t now= gettime_mon_frac(); // Make absolutely sure a forked child never runs the parent's // signal handler if (getpid() != sig_main_pid) { sig_reset_for_exec(); kill(getpid(), sig); } // We have a requirement that no two signals share a timestamp. if (now == prev) now++; // We also use '0' as a NULL value, so avoid it if (!now) now++; record_signal((sig_status_t*)new_signals, sizeof(new_signals)/sizeof(*new_signals), sig, now, 1); prev= now; // put character in pipe to wake main loop if (write(sig_wake_wr, "", 1) != 1) signal_error= errno; }
void merge_new_signals() { int i; sigset_t mask; // Block all signals, briefly sigfillset(&mask); if (sigprocmask(SIG_SETMASK, &mask, &mask) != 0) log_error("sigprocmask: %m"); // Add any new signals to the known signals for (i= 0; i < sizeof(new_signals)/sizeof(*new_signals); i++) { if (!new_signals[i].number_pending) break; record_signal(signals, sizeof(signals)/sizeof(*signals), new_signals[i].signum, new_signals[i].last_received_ts, new_signals[i].number_pending); } // Clean slate memset(&new_signals, 0, sizeof(new_signals)); //restore normal signal mask if (sigprocmask(SIG_SETMASK, &mask, &mask) != 0) log_error("sigprocmask: %m"); }
static void trapSIGFPE(int sig RECARG) { static const char *emsg[] = { /* FPE_NOOP 0*/ "SIGFPE", /* FPE_FLTDIV 1*/ "floating point divide by zero", /* FPE_FLTOVF 2*/ "floating point overflow", /* FPE_FLTUND 3*/ "floating point underflow", /* FPE_FLTRES 4*/ "floating point inexact result", /* FPE_FLTINV 5 */ "invalid floating point operation", /* FPE_FLTSUB 6 */ "subscript out of range", /* FPE_INTDIV 7 */ "integer divide by zero", /* FPE_INTOVF 8 */ "integer overflow"}; CTX ctx = knh_getCurrentContext(); record_signal(ctx, sig RECDATA); if(ctx != NULL) { #if defined(K_USING_MINGW_) int si_code = 0; #else int si_code = (si->si_code < 9) ? si->si_code : 0; #endif /* defined(K_USING_MINGW_) */ THROW_Arithmetic(ctx, NULL, emsg[si_code]); } }