8255711: Fix and unify hotspot signal handlers

Reviewed-by: coleenp, gziemski, dholmes
This commit is contained in:
Thomas Stuefe 2020-11-09 12:03:06 +00:00
parent d99e1f6c29
commit dd8e4ffbe5
15 changed files with 270 additions and 853 deletions

View file

@ -200,58 +200,10 @@ enum {
trap_page_fault = 0xE
};
extern "C" JNIEXPORT int
JVM_handle_linux_signal(int sig,
siginfo_t* info,
void* ucVoid,
int abort_if_unrecognized) {
ucontext_t* uc = (ucontext_t*) ucVoid;
bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
ucontext_t* uc, JavaThread* thread) {
Thread* t = Thread::current_or_null_safe();
// If crash protection is installed we may longjmp away and no destructors
// for objects in this scope will be run.
// So don't use any RAII utilities before crash protection is checked.
os::ThreadCrashProtection::check_crash_protection(sig, t);
// Note: it's not uncommon that JNI code uses signal/sigset to install
// then restore certain signal handler (e.g. to temporarily block SIGPIPE,
// or have a SIGILL handler when detecting CPU type). When that happens,
// JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
// avoid unnecessary crash when libjsig is not preloaded, try handle signals
// that do not require siginfo/ucontext first.
if (sig == SIGPIPE || sig == SIGXFSZ) {
// allow chained handler to go first
if (PosixSignals::chained_handler(sig, info, ucVoid)) {
return true;
} else {
// Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
return true;
}
}
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) {
if (handle_assert_poison_fault(ucVoid, info->si_addr)) {
return 1;
}
}
#endif
JavaThread* thread = NULL;
VMThread* vmthread = NULL;
if (PosixSignals::are_signal_handlers_installed()) {
if (t != NULL ){
if(t->is_Java_thread()) {
thread = t->as_Java_thread();
}
else if(t->is_VM_thread()){
vmthread = (VMThread *)t;
}
}
}
/*
/*
NOTE: does not seem to work on linux.
if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
// can't decode this kind of signal
@ -271,7 +223,7 @@ JVM_handle_linux_signal(int sig,
if (StubRoutines::is_safefetch_fault(pc)) {
os::Linux::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
return 1;
return true;
}
#ifndef AMD64
@ -292,7 +244,7 @@ JVM_handle_linux_signal(int sig,
if (thread->is_in_full_stack(addr)) {
// stack overflow
if (os::Posix::handle_stack_overflow(thread, addr, pc, uc, &stub)) {
return 1; // continue
return true; // continue
}
}
}
@ -469,30 +421,7 @@ JVM_handle_linux_signal(int sig,
return true;
}
// signal-chaining
if (PosixSignals::chained_handler(sig, info, ucVoid)) {
return true;
}
if (!abort_if_unrecognized) {
// caller wants another chance, so give it to him
return false;
}
if (pc == NULL && uc != NULL) {
pc = os::Linux::ucontext_get_pc(uc);
}
// unmask current signal
sigset_t newset;
sigemptyset(&newset);
sigaddset(&newset, sig);
sigprocmask(SIG_UNBLOCK, &newset, NULL);
VMError::report_and_die(t, sig, pc, info, ucVoid);
ShouldNotReachHere();
return true; // Mute compiler
return false;
}
void os::Linux::init_thread_fpu_state(void) {