Don't suppresse prev signal handler in hw bound check

This commit is contained in:
Wenyong Huang 2022-07-06 22:15:36 +08:00
parent 653efecd02
commit 80bd8357eb

View File

@ -448,31 +448,53 @@ mask_signals(int how)
pthread_sigmask(how, &set, NULL); pthread_sigmask(how, &set, NULL);
} }
__attribute__((noreturn)) static void static struct sigaction prev_sig_act_SIGSEGV;
static struct sigaction prev_sig_act_SIGBUS;
static void
signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext) signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext)
{ {
void *sig_addr = sig_info->si_addr; void *sig_addr = sig_info->si_addr;
struct sigaction *prev_sig_act = NULL;
mask_signals(SIG_BLOCK); mask_signals(SIG_BLOCK);
/* Try to handle signal with the registered signal handler */
if (signal_handler && (sig_num == SIGSEGV || sig_num == SIGBUS)) { if (signal_handler && (sig_num == SIGSEGV || sig_num == SIGBUS)) {
signal_handler(sig_addr); signal_handler(sig_addr);
} }
/* signal unhandled */ if (sig_num == SIGSEGV)
switch (sig_num) { prev_sig_act = &prev_sig_act_SIGSEGV;
case SIGSEGV: else if (sig_num == SIGBUS)
os_printf("unhandled SIGSEGV, si_addr: %p\n", sig_addr); prev_sig_act = &prev_sig_act_SIGBUS;
break;
case SIGBUS:
os_printf("unhandled SIGBUS, si_addr: %p\n", sig_addr);
break;
default:
os_printf("unhandle signal %d, si_addr: %p\n", sig_num, sig_addr);
break;
}
abort(); /* Forward the signal to next handler if found */
if (prev_sig_act && (prev_sig_act->sa_flags & SA_SIGINFO)) {
prev_sig_act->sa_sigaction(sig_num, sig_info, sig_ucontext);
}
else if (prev_sig_act
&& ((void *)prev_sig_act->sa_sigaction == SIG_DFL
|| (void *)prev_sig_act->sa_sigaction == SIG_IGN)) {
sigaction(sig_num, prev_sig_act, NULL);
}
/* Output signal info and then crash if signal is unhandled */
else {
switch (sig_num) {
case SIGSEGV:
os_printf("unhandled SIGSEGV, si_addr: %p\n", sig_addr);
break;
case SIGBUS:
os_printf("unhandled SIGBUS, si_addr: %p\n", sig_addr);
break;
default:
os_printf("unhandle signal %d, si_addr: %p\n", sig_num,
sig_addr);
break;
}
abort();
}
} }
int int
@ -508,12 +530,15 @@ os_thread_signal_init(os_signal_handler handler)
goto fail2; goto fail2;
} }
memset(&prev_sig_act_SIGSEGV, 0, sizeof(struct sigaction));
memset(&prev_sig_act_SIGBUS, 0, sizeof(struct sigaction));
/* Install signal hanlder */ /* Install signal hanlder */
sig_act.sa_sigaction = signal_callback; sig_act.sa_sigaction = signal_callback;
sig_act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_NODEFER; sig_act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_NODEFER;
sigemptyset(&sig_act.sa_mask); sigemptyset(&sig_act.sa_mask);
if (sigaction(SIGSEGV, &sig_act, NULL) != 0 if (sigaction(SIGSEGV, &sig_act, &prev_sig_act_SIGSEGV) != 0
|| sigaction(SIGBUS, &sig_act, NULL) != 0) { || sigaction(SIGBUS, &sig_act, &prev_sig_act_SIGBUS) != 0) {
os_printf("Failed to register signal handler\n"); os_printf("Failed to register signal handler\n");
goto fail3; goto fail3;
} }