mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 03:24:38 +02:00
8255711: Fix and unify hotspot signal handlers
Reviewed-by: coleenp, gziemski, dholmes
This commit is contained in:
parent
d99e1f6c29
commit
dd8e4ffbe5
15 changed files with 270 additions and 853 deletions
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue