mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14: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
|
@ -188,32 +188,8 @@ frame os::current_frame() {
|
|||
return os::get_sender_for_C_frame(&tmp);
|
||||
}
|
||||
|
||||
// Utility functions
|
||||
|
||||
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;
|
||||
|
||||
Thread* t = Thread::current_or_null_safe();
|
||||
|
||||
// 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) {
|
||||
if (PosixSignals::chained_handler(sig, info, ucVoid)) {
|
||||
return true;
|
||||
} else {
|
||||
// Ignoring SIGPIPE - see bugs 4229104
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
|
||||
ucontext_t* uc, JavaThread* thread) {
|
||||
|
||||
// Make the signal handler transaction-aware by checking the existence of a
|
||||
// second (transactional) context with MSR TS bits active. If the signal is
|
||||
|
@ -237,26 +213,6 @@ JVM_handle_linux_signal(int sig,
|
|||
}
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Moved SafeFetch32 handling outside thread!=NULL conditional block to make
|
||||
// it work if no associated JavaThread object exists.
|
||||
if (uc) {
|
||||
|
@ -297,7 +253,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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,17 +262,6 @@ JVM_handle_linux_signal(int sig,
|
|||
// Java thread running in Java code => find exception handler if any
|
||||
// a fault inside compiled code, the interpreter, or a stub
|
||||
|
||||
// A VM-related SIGILL may only occur if we are not in the zero page.
|
||||
// On AIX, we get a SIGILL if we jump to 0x0 or to somewhere else
|
||||
// in the zero page, because it is filled with 0x0. We ignore
|
||||
// explicit SIGILLs in the zero page.
|
||||
if (sig == SIGILL && (pc < (address) 0x200)) {
|
||||
if (TraceTraps) {
|
||||
tty->print_raw_cr("SIGILL happened inside zero page.");
|
||||
}
|
||||
goto report_and_die;
|
||||
}
|
||||
|
||||
CodeBlob *cb = NULL;
|
||||
int stop_type = -1;
|
||||
// Handle signal from NativeJump::patch_verified_entry().
|
||||
|
@ -404,10 +349,7 @@ JVM_handle_linux_signal(int sig,
|
|||
tty->print_cr("trap: %s: %s (SIGTRAP, stop type %d)", msg, detail_msg, stop_type);
|
||||
}
|
||||
|
||||
va_list detail_args;
|
||||
VMError::report_and_die(INTERNAL_ERROR, msg, detail_msg, detail_args, thread,
|
||||
pc, info, ucVoid, NULL, 0, 0);
|
||||
va_end(detail_args);
|
||||
return false; // Fatal error
|
||||
}
|
||||
|
||||
else if (sig == SIGBUS) {
|
||||
|
@ -465,31 +407,8 @@ 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);
|
||||
}
|
||||
|
||||
report_and_die:
|
||||
// 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 false;
|
||||
|
||||
}
|
||||
|
||||
void os::Linux::init_thread_fpu_state(void) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue