static void pth_thread_refl_fault(struct uthread *uthread, unsigned int trap_nr, unsigned int err, unsigned long aux) { struct pthread_tcb *pthread = (struct pthread_tcb*)uthread; pthread->state = PTH_BLK_SYSC; mcs_pdr_lock(&queue_lock); threads_active--; TAILQ_REMOVE(&active_queue, pthread, tq_next); mcs_pdr_unlock(&queue_lock); /* TODO: RISCV/x86 issue! (0 is divby0, 14 is PF, etc) */ #if defined(__i386__) || defined(__x86_64__) switch(trap_nr) { case 0: handle_div_by_zero(uthread, err, aux); break; case 13: handle_gp_fault(uthread, err, aux); break; case 14: handle_page_fault(uthread, err, aux); break; default: printf("Pthread has unhandled fault: %d, err: %d, aux: %p\n", trap_nr, err, aux); /* Note that uthread.c already copied out our ctx into the uth * struct */ print_user_context(&uthread->u_ctx); printf("Turn on printx to spew unhandled, malignant trap info\n"); exit(-1); } #else #error "Handling hardware faults is currently only supported on x86" #endif }
static void thread0_thread_refl_fault(struct uthread *uthread, unsigned int trap_nr, unsigned int err, unsigned long aux) { printf("SCP has unhandled fault: %d, err: %d, aux: %p\n", trap_nr, err, aux); print_user_context(&uthread->u_ctx); printf("Turn on printx to spew unhandled, malignant trap info\n"); exit(-1); }
static void refl_error(struct uthread *uth, unsigned int trap_nr, unsigned int err, unsigned long aux) { printf("Thread has unhandled fault: %d, err: %d, aux: %p\n", trap_nr, err, aux); /* Note that uthread.c already copied out our ctx into the uth * struct */ print_user_context(&uth->u_ctx); printf("Turn on printx to spew unhandled, malignant trap info\n"); exit(-1); }
static void default_core_handler(int signr, siginfo_t *info, void *ctx) { printf("Segmentation Fault (sorry, no core dump yet)\n"); if (ctx) print_user_context((struct user_context*)ctx); else printf("No ctx for %s\n", __func__); if (info) { /* ghetto, we don't have access to the PF err, since we only have a few * fields available in siginfo (e.g. there's no si_trapno). */ printf("Fault type %d at addr %p\n", info->si_errno, info->si_addr); } else { printf("No fault info\n"); } default_term_handler((1 << 7) + signr, info, ctx); }
/* If the given signal is unmasked, prep the pthread to run it's signal * handler, but don't run it yet. In either case, make the pthread runnable * again. Once the signal handler is complete, the original context will be * restored and restarted. */ static void __pthread_signal_and_restart(struct pthread_tcb *pthread, int signo, int code, void *addr) { if (!__sigismember(&pthread->sigmask, signo)) { if (pthread->sigdata) { printf("Pthread sighandler faulted, signal: %d\n", signo); /* uthread.c already copied out the faulting ctx into the uth */ print_user_context(&pthread->uthread.u_ctx); exit(-1); } struct siginfo info = {0}; info.si_signo = signo; info.si_code = code; info.si_addr = addr; __pthread_prep_sighandler(pthread, __run_sighandler, &info); } pth_thread_runnable(&pthread->uthread); }