@@ -451,46 +451,62 @@ extern "C" JNIEXPORT int JVM_handle_linux_signal(int signo, siginfo_t* siginfo,
451
451
int abort_if_unrecognized);
452
452
#endif
453
453
454
- #if defined(AIX)
455
454
456
- // Set thread signal mask (for some reason on AIX sigthreadmask() seems
457
- // to be the thing to call; documentation is not terribly clear about whether
458
- // pthread_sigmask also works, and if it does, whether it does the same.
459
- bool set_thread_signal_mask (int how, const sigset_t * set, sigset_t * oset) {
460
- const int rc = ::pthread_sigmask (how, set, oset);
461
- // return value semantics differ slightly for error case:
462
- // pthread_sigmask returns error number, sigthreadmask -1 and sets global errno
463
- // (so, pthread_sigmask is more theadsafe for error handling)
464
- // But success is always 0.
465
- return rc == 0 ? true : false ;
455
+ // /// Synchronous (non-deferrable) error signals (ILL, SEGV, FPE, BUS, TRAP):
456
+
457
+ // These signals are special because they cannot be deferred and, if they
458
+ // happen while delivery is blocked for the receiving thread, will cause UB
459
+ // (in practice typically resulting in sudden process deaths or hangs, see
460
+ // JDK-8252533). So we must take care never to block them when we cannot be
461
+ // absolutely sure they won't happen. In practice, this is always.
462
+ //
463
+ // Relevant Posix quote:
464
+ // "The behavior of a process is undefined after it ignores a SIGFPE, SIGILL,
465
+ // SIGSEGV, or SIGBUS signal that was not generated by kill(), sigqueue(), or
466
+ // raise()."
467
+ //
468
+ // We also include SIGTRAP in that list of never-to-block-signals. While not
469
+ // mentioned by the Posix documentation, in our (SAPs) experience blocking it
470
+ // causes similar problems. Beside, during normal operation - outside of error
471
+ // handling - SIGTRAP may be used for implicit NULL checking, so it makes sense
472
+ // to never block it.
473
+ //
474
+ // We deal with those signals in two ways:
475
+ // - we just never explicitly block them, which includes not accidentally blocking
476
+ // them via sa_mask when establishing signal handlers.
477
+ // - as an additional safety measure, at the entrance of a signal handler, we
478
+ // unblock them explicitly.
479
+
480
+ static void add_error_signals_to_set (sigset_t * set) {
481
+ sigaddset (set, SIGILL);
482
+ sigaddset (set, SIGBUS);
483
+ sigaddset (set, SIGFPE);
484
+ sigaddset (set, SIGSEGV);
485
+ sigaddset (set, SIGTRAP);
486
+ }
487
+
488
+ static void remove_error_signals_from_set (sigset_t * set) {
489
+ sigdelset (set, SIGILL);
490
+ sigdelset (set, SIGBUS);
491
+ sigdelset (set, SIGFPE);
492
+ sigdelset (set, SIGSEGV);
493
+ sigdelset (set, SIGTRAP);
466
494
}
467
495
468
- // Function to unblock all signals which are, according
469
- // to POSIX, typical program error signals. If they happen while being blocked,
470
- // they typically will bring down the process immediately.
471
- bool unblock_program_error_signals () {
496
+ // Unblock all signals whose delivery cannot be deferred and which, if they happen
497
+ // while delivery is blocked, would cause crashes or hangs (JDK-8252533).
498
+ void PosixSignals::unblock_error_signals () {
472
499
sigset_t set;
473
500
sigemptyset (&set);
474
- sigaddset (&set, SIGILL);
475
- sigaddset (&set, SIGBUS);
476
- sigaddset (&set, SIGFPE);
477
- sigaddset (&set, SIGSEGV);
478
- return set_thread_signal_mask (SIG_UNBLOCK, &set, NULL );
501
+ add_error_signals_to_set (&set);
502
+ ::pthread_sigmask (SIG_UNBLOCK, &set, NULL );
479
503
}
480
504
481
- #endif
482
-
483
505
// Renamed from 'signalHandler' to avoid collision with other shared libs.
484
506
static void javaSignalHandler (int sig, siginfo_t * info, void * uc) {
485
507
assert (info != NULL && uc != NULL , " it must be old kernel" );
486
508
487
- // TODO: reconcile the differences between Linux/BSD vs AIX here!
488
- #if defined(AIX)
489
- // Never leave program error signals blocked;
490
- // on all our platforms they would bring down the process immediately when
491
- // getting raised while being blocked.
492
- unblock_program_error_signals ();
493
- #endif
509
+ PosixSignals::unblock_error_signals ();
494
510
495
511
int orig_errno = errno; // Preserve errno value over signal handler.
496
512
#if defined(BSD)
@@ -504,6 +520,9 @@ static void javaSignalHandler(int sig, siginfo_t* info, void* uc) {
504
520
}
505
521
506
522
static void UserHandler (int sig, void *siginfo, void *context) {
523
+
524
+ PosixSignals::unblock_error_signals ();
525
+
507
526
// Ctrl-C is pressed during error reporting, likely because the error
508
527
// handler fails to abort. Let VM die immediately.
509
528
if (sig == SIGINT && VMError::is_error_reported ()) {
@@ -702,23 +721,7 @@ void* os::signal(int signal_number, void* handler) {
702
721
struct sigaction sigAct, oldSigAct;
703
722
704
723
sigfillset (&(sigAct.sa_mask ));
705
-
706
- #if defined(AIX)
707
- // Do not block out synchronous signals in the signal handler.
708
- // Blocking synchronous signals only makes sense if you can really
709
- // be sure that those signals won't happen during signal handling,
710
- // when the blocking applies. Normal signal handlers are lean and
711
- // do not cause signals. But our signal handlers tend to be "risky"
712
- // - secondary SIGSEGV, SIGILL, SIGBUS' may and do happen.
713
- // On AIX, PASE there was a case where a SIGSEGV happened, followed
714
- // by a SIGILL, which was blocked due to the signal mask. The process
715
- // just hung forever. Better to crash from a secondary signal than to hang.
716
- sigdelset (&(sigAct.sa_mask ), SIGSEGV);
717
- sigdelset (&(sigAct.sa_mask ), SIGBUS);
718
- sigdelset (&(sigAct.sa_mask ), SIGILL);
719
- sigdelset (&(sigAct.sa_mask ), SIGFPE);
720
- sigdelset (&(sigAct.sa_mask ), SIGTRAP);
721
- #endif
724
+ remove_error_signals_from_set (&(sigAct.sa_mask ));
722
725
723
726
sigAct.sa_flags = SA_RESTART|SA_SIGINFO;
724
727
sigAct.sa_handler = CAST_TO_FN_PTR (sa_handler_t , handler);
@@ -1099,6 +1102,7 @@ void set_signal_handler(int sig, bool set_installed) {
1099
1102
1100
1103
struct sigaction sigAct;
1101
1104
sigfillset (&(sigAct.sa_mask ));
1105
+ remove_error_signals_from_set (&(sigAct.sa_mask ));
1102
1106
sigAct.sa_handler = SIG_DFL;
1103
1107
if (!set_installed) {
1104
1108
sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
@@ -1303,10 +1307,6 @@ bool PosixSignals::is_sig_ignored(int sig) {
1303
1307
}
1304
1308
}
1305
1309
1306
- int PosixSignals::unblock_thread_signal_mask (const sigset_t *set) {
1307
- return pthread_sigmask (SIG_UNBLOCK, set, NULL );
1308
- }
1309
-
1310
1310
address PosixSignals::ucontext_get_pc (const ucontext_t * ctx) {
1311
1311
#if defined(AIX)
1312
1312
return os::Aix::ucontext_get_pc (ctx);
@@ -1470,10 +1470,13 @@ static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontex
1470
1470
// Currently only ever called on the VMThread and JavaThreads (PC sampling)
1471
1471
//
1472
1472
static void SR_handler (int sig, siginfo_t * siginfo, ucontext_t * context) {
1473
+
1473
1474
// Save and restore errno to avoid confusing native code with EINTR
1474
1475
// after sigsuspend.
1475
1476
int old_errno = errno;
1476
1477
1478
+ PosixSignals::unblock_error_signals ();
1479
+
1477
1480
Thread* thread = Thread::current_or_null_safe ();
1478
1481
assert (thread != NULL , " Missing current thread in SR_handler" );
1479
1482
@@ -1567,6 +1570,7 @@ int PosixSignals::SR_initialize() {
1567
1570
1568
1571
// SR_signum is blocked by default.
1569
1572
pthread_sigmask (SIG_BLOCK, NULL , &act.sa_mask );
1573
+ remove_error_signals_from_set (&(act.sa_mask ));
1570
1574
1571
1575
if (sigaction (SR_signum, &act, 0 ) == -1 ) {
1572
1576
return -1 ;
0 commit comments