Skip to content

Commit dd8e4ff

Browse files
committed
8255711: Fix and unify hotspot signal handlers
Reviewed-by: coleenp, gziemski, dholmes
1 parent d99e1f6 commit dd8e4ff

File tree

15 files changed

+269
-852
lines changed

15 files changed

+269
-852
lines changed

make/hotspot/symbols/symbols-aix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
# questions.
2222
#
2323

24-
JVM_handle_linux_signal
24+
JVM_handle_aix_signal
2525
numa_error
2626
numa_warn
2727
sysThreadAvailableStackWithSlack

src/hotspot/os/posix/signals_posix.cpp

Lines changed: 209 additions & 144 deletions
Large diffs are not rendered by default.

src/hotspot/os/posix/signals_posix.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ class PosixSignals : public AllStatic {
3838

3939
public:
4040

41-
static bool are_signal_handlers_installed();
41+
// The platform dependent parts of the central hotspot signal handler.
42+
// Returns true if the signal had been recognized and handled, false if not. If true, caller should
43+
// return from signal handling.
44+
static bool pd_hotspot_signal_handler(int sig, siginfo_t* info, ucontext_t* uc, JavaThread* thread);
45+
4246
static void install_signal_handlers();
4347

4448
static bool is_sig_ignored(int sig);

src/hotspot/os/windows/os_windows.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,6 +2144,8 @@ static int check_pending_signals() {
21442144
}
21452145
} while (threadIsSuspended);
21462146
}
2147+
ShouldNotReachHere();
2148+
return 0; // Satisfy compiler
21472149
}
21482150

21492151
int os::signal_wait() {

src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp

Lines changed: 11 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -168,43 +168,8 @@ frame os::current_frame() {
168168
return os::get_sender_for_C_frame(&tmp);
169169
}
170170

171-
// Utility functions
172-
173-
extern "C" JNIEXPORT int
174-
JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrecognized) {
175-
176-
ucontext_t* uc = (ucontext_t*) ucVoid;
177-
178-
Thread* t = Thread::current_or_null_safe();
179-
180-
// Note: it's not uncommon that JNI code uses signal/sigset to install
181-
// then restore certain signal handler (e.g. to temporarily block SIGPIPE,
182-
// or have a SIGILL handler when detecting CPU type). When that happens,
183-
// JVM_handle_aix_signal() might be invoked with junk info/ucVoid. To
184-
// avoid unnecessary crash when libjsig is not preloaded, try handle signals
185-
// that do not require siginfo/ucontext first.
186-
187-
if (sig == SIGPIPE || sig == SIGXFSZ) {
188-
if (PosixSignals::chained_handler(sig, info, ucVoid)) {
189-
return 1;
190-
} else {
191-
// Ignoring SIGPIPE - see bugs 4229104
192-
return 1;
193-
}
194-
}
195-
196-
JavaThread* thread = NULL;
197-
VMThread* vmthread = NULL;
198-
if (PosixSignals::are_signal_handlers_installed()) {
199-
if (t != NULL) {
200-
if(t->is_Java_thread()) {
201-
thread = t->as_Java_thread();
202-
}
203-
else if(t->is_VM_thread()) {
204-
vmthread = (VMThread *)t;
205-
}
206-
}
207-
}
171+
bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
172+
ucontext_t* uc, JavaThread* thread) {
208173

209174
// Decide if this trap can be handled by a stub.
210175
address stub = NULL;
@@ -226,8 +191,8 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
226191
}
227192
}
228193

229-
if (info == NULL || uc == NULL || thread == NULL && vmthread == NULL) {
230-
goto run_chained_handler;
194+
if (info == NULL || uc == NULL) {
195+
return false; // Fatal error
231196
}
232197

233198
// If we are a java thread...
@@ -237,11 +202,11 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
237202
if (sig == SIGSEGV && thread->is_in_full_stack(addr)) {
238203
// stack overflow
239204
if (os::Posix::handle_stack_overflow(thread, addr, pc, uc, &stub)) {
240-
return 1; // continue
205+
return true; // continue
241206
} else if (stub != NULL) {
242207
goto run_stub;
243208
} else {
244-
goto report_and_die;
209+
return false; // Fatal error
245210
}
246211
} // end handle SIGSEGV inside stack boundaries
247212

@@ -281,17 +246,6 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
281246
// happens rarely. In heap based and disjoint base compressd oop modes also loads
282247
// are used for null checks.
283248

284-
// A VM-related SIGILL may only occur if we are not in the zero page.
285-
// On AIX, we get a SIGILL if we jump to 0x0 or to somewhere else
286-
// in the zero page, because it is filled with 0x0. We ignore
287-
// explicit SIGILLs in the zero page.
288-
if (sig == SIGILL && (pc < (address) 0x200)) {
289-
if (TraceTraps) {
290-
tty->print_raw_cr("SIGILL happened inside zero page.");
291-
}
292-
goto report_and_die;
293-
}
294-
295249
int stop_type = -1;
296250
// Handle signal from NativeJump::patch_verified_entry().
297251
if (sig == SIGILL && nativeInstruction_at(pc)->is_sigill_zombie_not_entrant()) {
@@ -384,10 +338,7 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
384338
tty->print_cr("trap: %s: %s (SIGTRAP, stop type %d)", msg, detail_msg, stop_type);
385339
}
386340

387-
va_list detail_args;
388-
VMError::report_and_die(INTERNAL_ERROR, msg, detail_msg, detail_args, thread,
389-
pc, info, ucVoid, NULL, 0, 0);
390-
va_end(detail_args);
341+
return false; // Fatal error
391342
}
392343

393344
else if (sig == SIGBUS) {
@@ -403,7 +354,7 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
403354
}
404355
next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
405356
os::Aix::ucontext_set_pc(uc, next_pc);
406-
return 1;
357+
return true;
407358
}
408359
}
409360
}
@@ -428,7 +379,7 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
428379
}
429380
next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
430381
os::Aix::ucontext_set_pc(uc, next_pc);
431-
return 1;
382+
return true;
432383
}
433384
}
434385

@@ -450,32 +401,10 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
450401
// Save all thread context in case we need to restore it.
451402
if (thread != NULL) thread->set_saved_exception_pc(pc);
452403
os::Aix::ucontext_set_pc(uc, stub);
453-
return 1;
454-
}
455-
456-
run_chained_handler:
457-
458-
// signal-chaining
459-
if (PosixSignals::chained_handler(sig, info, ucVoid)) {
460-
return 1;
404+
return true;
461405
}
462-
if (!abort_if_unrecognized) {
463-
// caller wants another chance, so give it to him
464-
return 0;
465-
}
466-
467-
report_and_die:
468406

469-
// Use sigthreadmask instead of sigprocmask on AIX and unmask current signal.
470-
sigset_t newset;
471-
sigemptyset(&newset);
472-
sigaddset(&newset, sig);
473-
sigthreadmask(SIG_UNBLOCK, &newset, NULL);
474-
475-
VMError::report_and_die(t, sig, pc, info, ucVoid);
476-
477-
ShouldNotReachHere();
478-
return 0;
407+
return false; // Fatal error
479408
}
480409

481410
void os::Aix::init_thread_fpu_state(void) {

src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp

Lines changed: 4 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -385,56 +385,14 @@ frame os::current_frame() {
385385
}
386386
}
387387

388-
// Utility functions
389-
390388
// From IA32 System Programming Guide
391389
enum {
392390
trap_page_fault = 0xE
393391
};
394392

395-
extern "C" JNIEXPORT int
396-
JVM_handle_bsd_signal(int sig,
397-
siginfo_t* info,
398-
void* ucVoid,
399-
int abort_if_unrecognized) {
400-
ucontext_t* uc = (ucontext_t*) ucVoid;
401-
402-
Thread* t = Thread::current_or_null_safe();
403-
404-
// If crash protection is installed we may longjmp away and no destructors
405-
// for objects in this scope will be run.
406-
// So don't use any RAII utilities before crash protection is checked.
407-
os::ThreadCrashProtection::check_crash_protection(sig, t);
408-
409-
// Note: it's not uncommon that JNI code uses signal/sigset to install
410-
// then restore certain signal handler (e.g. to temporarily block SIGPIPE,
411-
// or have a SIGILL handler when detecting CPU type). When that happens,
412-
// JVM_handle_bsd_signal() might be invoked with junk info/ucVoid. To
413-
// avoid unnecessary crash when libjsig is not preloaded, try handle signals
414-
// that do not require siginfo/ucontext first.
415-
416-
if (sig == SIGPIPE || sig == SIGXFSZ) {
417-
// allow chained handler to go first
418-
if (PosixSignals::chained_handler(sig, info, ucVoid)) {
419-
return true;
420-
} else {
421-
// Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
422-
return true;
423-
}
424-
}
393+
bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
394+
ucontext_t* uc, JavaThread* thread) {
425395

426-
JavaThread* thread = NULL;
427-
VMThread* vmthread = NULL;
428-
if (PosixSignals::are_signal_handlers_installed()) {
429-
if (t != NULL ){
430-
if(t->is_Java_thread()) {
431-
thread = t->as_Java_thread();
432-
}
433-
else if(t->is_VM_thread()){
434-
vmthread = (VMThread *)t;
435-
}
436-
}
437-
}
438396
/*
439397
NOTE: does not seem to work on bsd.
440398
if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
@@ -455,7 +413,7 @@ JVM_handle_bsd_signal(int sig,
455413

456414
if (StubRoutines::is_safefetch_fault(pc)) {
457415
os::Bsd::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
458-
return 1;
416+
return true;
459417
}
460418

461419
// Handle ALL stack overflow variations here
@@ -466,7 +424,7 @@ JVM_handle_bsd_signal(int sig,
466424
if (thread->is_in_full_stack(addr)) {
467425
// stack overflow
468426
if (os::Posix::handle_stack_overflow(thread, addr, pc, uc, &stub)) {
469-
return 1; // continue
427+
return true; // continue
470428
}
471429
}
472430
}
@@ -678,29 +636,6 @@ JVM_handle_bsd_signal(int sig,
678636
return true;
679637
}
680638

681-
// signal-chaining
682-
if (PosixSignals::chained_handler(sig, info, ucVoid)) {
683-
return true;
684-
}
685-
686-
if (!abort_if_unrecognized) {
687-
// caller wants another chance, so give it to him
688-
return false;
689-
}
690-
691-
if (pc == NULL && uc != NULL) {
692-
pc = os::Bsd::ucontext_get_pc(uc);
693-
}
694-
695-
// unmask current signal
696-
sigset_t newset;
697-
sigemptyset(&newset);
698-
sigaddset(&newset, sig);
699-
sigprocmask(SIG_UNBLOCK, &newset, NULL);
700-
701-
VMError::report_and_die(t, sig, pc, info, ucVoid);
702-
703-
ShouldNotReachHere();
704639
return false;
705640
}
706641

src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp

Lines changed: 3 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -115,54 +115,17 @@ frame os::fetch_frame_from_context(const void* ucVoid) {
115115
return frame();
116116
}
117117

118-
extern "C" JNIEXPORT int
119-
JVM_handle_bsd_signal(int sig,
120-
siginfo_t* info,
121-
void* ucVoid,
122-
int abort_if_unrecognized) {
123-
ucontext_t* uc = (ucontext_t*) ucVoid;
118+
bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
119+
ucontext_t* uc, JavaThread* thread) {
124120

125-
Thread* t = Thread::current_or_null_safe();
126-
127-
// handle SafeFetch faults
121+
// handle SafeFetch faults the zero way
128122
if (sig == SIGSEGV || sig == SIGBUS) {
129123
sigjmp_buf* const pjb = get_jmp_buf_for_continuation();
130124
if (pjb) {
131125
siglongjmp(*pjb, 1);
132126
}
133127
}
134128

135-
// Note: it's not uncommon that JNI code uses signal/sigset to
136-
// install then restore certain signal handler (e.g. to temporarily
137-
// block SIGPIPE, or have a SIGILL handler when detecting CPU
138-
// type). When that happens, JVM_handle_bsd_signal() might be
139-
// invoked with junk info/ucVoid. To avoid unnecessary crash when
140-
// libjsig is not preloaded, try handle signals that do not require
141-
// siginfo/ucontext first.
142-
143-
if (sig == SIGPIPE || sig == SIGXFSZ) {
144-
// allow chained handler to go first
145-
if (PosixSignals::chained_handler(sig, info, ucVoid)) {
146-
return true;
147-
} else {
148-
// Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219
149-
return true;
150-
}
151-
}
152-
153-
JavaThread* thread = NULL;
154-
VMThread* vmthread = NULL;
155-
if (PosixSignals::are_signal_handlers_installed()) {
156-
if (t != NULL ){
157-
if(t->is_Java_thread()) {
158-
thread = t->as_Java_thread();
159-
}
160-
else if(t->is_VM_thread()){
161-
vmthread = (VMThread *)t;
162-
}
163-
}
164-
}
165-
166129
if (info != NULL && thread != NULL) {
167130
// Handle ALL stack overflow variations here
168131
if (sig == SIGSEGV || sig == SIGBUS) {
@@ -202,36 +165,6 @@ JVM_handle_bsd_signal(int sig,
202165
}*/
203166
}
204167

205-
// signal-chaining
206-
if (PosixSignals::chained_handler(sig, info, ucVoid)) {
207-
return true;
208-
}
209-
210-
if (!abort_if_unrecognized) {
211-
// caller wants another chance, so give it to him
212-
return false;
213-
}
214-
215-
#ifndef PRODUCT
216-
if (sig == SIGSEGV) {
217-
fatal("\n#"
218-
"\n# /--------------------\\"
219-
"\n# | segmentation fault |"
220-
"\n# \\---\\ /--------------/"
221-
"\n# /"
222-
"\n# [-] |\\_/| "
223-
"\n# (+)=C |o o|__ "
224-
"\n# | | =-*-=__\\ "
225-
"\n# OOO c_c_(___)");
226-
}
227-
#endif // !PRODUCT
228-
229-
const char *fmt =
230-
"caught unhandled signal " INT32_FORMAT " at address " PTR_FORMAT;
231-
char buf[128];
232-
233-
sprintf(buf, fmt, sig, info->si_addr);
234-
fatal(buf);
235168
return false;
236169
}
237170

0 commit comments

Comments
 (0)