4446 // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
4447 //
4448 extern "C" JNIEXPORT int JVM_handle_linux_signal(int signo,
4449 siginfo_t* siginfo,
4450 void* ucontext,
4451 int abort_if_unrecognized);
4452
4453 static void signalHandler(int sig, siginfo_t* info, void* uc) {
4454 assert(info != NULL && uc != NULL, "it must be old kernel");
4455 int orig_errno = errno; // Preserve errno value over signal handler.
4456 JVM_handle_linux_signal(sig, info, uc, true);
4457 errno = orig_errno;
4458 }
4459
4460
4461 // This boolean allows users to forward their own non-matching signals
4462 // to JVM_handle_linux_signal, harmlessly.
4463 bool os::Linux::signal_handlers_are_installed = false;
4464
4465 // For signal-chaining
4466 struct sigaction sigact[NSIG];
4467 uint64_t sigs = 0;
4468 #if (64 < NSIG-1)
4469 #error "Not all signals can be encoded in sigs. Adapt its type!"
4470 #endif
4471 bool os::Linux::libjsig_is_loaded = false;
4472 typedef struct sigaction *(*get_signal_t)(int);
4473 get_signal_t os::Linux::get_signal_action = NULL;
4474
4475 struct sigaction* os::Linux::get_chained_signal_action(int sig) {
4476 struct sigaction *actp = NULL;
4477
4478 if (libjsig_is_loaded) {
4479 // Retrieve the old signal handler from libjsig
4480 actp = (*get_signal_action)(sig);
4481 }
4482 if (actp == NULL) {
4483 // Retrieve the preinstalled signal handler from jvm
4484 actp = get_preinstalled_handler(sig);
4485 }
4486
4487 return actp;
4488 }
4489
4490 static bool call_chained_handler(struct sigaction *actp, int sig,
4491 siginfo_t *siginfo, void *context) {
4492 // Call the old signal handler
4493 if (actp->sa_handler == SIG_DFL) {
4494 // It's more reasonable to let jvm treat it as an unexpected exception
4495 // instead of taking the default action.
4496 return false;
4497 } else if (actp->sa_handler != SIG_IGN) {
4498 if ((actp->sa_flags & SA_NODEFER) == 0) {
4499 // automaticlly block the signal
4500 sigaddset(&(actp->sa_mask), sig);
4501 }
4502
4503 sa_handler_t hand = NULL;
4504 sa_sigaction_t sa = NULL;
4528
4529 // restore the signal mask
4530 pthread_sigmask(SIG_SETMASK, &oset, NULL);
4531 }
4532 // Tell jvm's signal handler the signal is taken care of.
4533 return true;
4534 }
4535
4536 bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) {
4537 bool chained = false;
4538 // signal-chaining
4539 if (UseSignalChaining) {
4540 struct sigaction *actp = get_chained_signal_action(sig);
4541 if (actp != NULL) {
4542 chained = call_chained_handler(actp, sig, siginfo, context);
4543 }
4544 }
4545 return chained;
4546 }
4547
4548 struct sigaction* os::Linux::get_preinstalled_handler(int sig) {
4549 if ((((uint64_t)1 << (sig-1)) & sigs) != 0) {
4550 return &sigact[sig];
4551 }
4552 return NULL;
4553 }
4554
4555 void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
4556 assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
4557 sigact[sig] = oldAct;
4558 sigs |= (uint64_t)1 << (sig-1);
4559 }
4560
4561 // for diagnostic
4562 int sigflags[NSIG];
4563
4564 int os::Linux::get_our_sigflags(int sig) {
4565 assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
4566 return sigflags[sig];
4567 }
4568
4569 void os::Linux::set_our_sigflags(int sig, int flags) {
4570 assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
4571 if (sig > 0 && sig < NSIG) {
4572 sigflags[sig] = flags;
4573 }
4574 }
4575
4576 void os::Linux::set_signal_handler(int sig, bool set_installed) {
4577 // Check for overwrite.
4578 struct sigaction oldAct;
4579 sigaction(sig, (struct sigaction*)NULL, &oldAct);
4580
4581 void* oldhand = oldAct.sa_sigaction
4582 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
4583 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
4584 if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
4585 oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
4586 oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) {
4587 if (AllowUserSignalHandlers || !set_installed) {
4588 // Do not overwrite; user takes responsibility to forward to us.
4589 return;
4590 } else if (UseSignalChaining) {
4591 // save the old handler in jvm
4592 save_preinstalled_handler(sig, oldAct);
4593 // libjsig also interposes the sigaction() call below and saves the
4594 // old sigaction on it own.
4595 } else {
4596 fatal("Encountered unexpected pre-existing sigaction handler "
4597 "%#lx for signal %d.", (long)oldhand, sig);
4598 }
4599 }
4600
4601 struct sigaction sigAct;
4602 sigfillset(&(sigAct.sa_mask));
4603 sigAct.sa_handler = SIG_DFL;
4604 if (!set_installed) {
4605 sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
4606 } else {
4607 sigAct.sa_sigaction = signalHandler;
4608 sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
4609 }
4610 // Save flags, which are set by ours
4611 assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
4612 sigflags[sig] = sigAct.sa_flags;
|
4446 // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
4447 //
4448 extern "C" JNIEXPORT int JVM_handle_linux_signal(int signo,
4449 siginfo_t* siginfo,
4450 void* ucontext,
4451 int abort_if_unrecognized);
4452
4453 static void signalHandler(int sig, siginfo_t* info, void* uc) {
4454 assert(info != NULL && uc != NULL, "it must be old kernel");
4455 int orig_errno = errno; // Preserve errno value over signal handler.
4456 JVM_handle_linux_signal(sig, info, uc, true);
4457 errno = orig_errno;
4458 }
4459
4460
4461 // This boolean allows users to forward their own non-matching signals
4462 // to JVM_handle_linux_signal, harmlessly.
4463 bool os::Linux::signal_handlers_are_installed = false;
4464
4465 // For signal-chaining
4466 bool os::Linux::libjsig_is_loaded = false;
4467 typedef struct sigaction *(*get_signal_t)(int);
4468 get_signal_t os::Linux::get_signal_action = NULL;
4469
4470 struct sigaction* os::Linux::get_chained_signal_action(int sig) {
4471 struct sigaction *actp = NULL;
4472
4473 if (libjsig_is_loaded) {
4474 // Retrieve the old signal handler from libjsig
4475 actp = (*get_signal_action)(sig);
4476 }
4477 if (actp == NULL) {
4478 // Retrieve the preinstalled signal handler from jvm
4479 actp = os::Posix::get_preinstalled_handler(sig);
4480 }
4481
4482 return actp;
4483 }
4484
4485 static bool call_chained_handler(struct sigaction *actp, int sig,
4486 siginfo_t *siginfo, void *context) {
4487 // Call the old signal handler
4488 if (actp->sa_handler == SIG_DFL) {
4489 // It's more reasonable to let jvm treat it as an unexpected exception
4490 // instead of taking the default action.
4491 return false;
4492 } else if (actp->sa_handler != SIG_IGN) {
4493 if ((actp->sa_flags & SA_NODEFER) == 0) {
4494 // automaticlly block the signal
4495 sigaddset(&(actp->sa_mask), sig);
4496 }
4497
4498 sa_handler_t hand = NULL;
4499 sa_sigaction_t sa = NULL;
4523
4524 // restore the signal mask
4525 pthread_sigmask(SIG_SETMASK, &oset, NULL);
4526 }
4527 // Tell jvm's signal handler the signal is taken care of.
4528 return true;
4529 }
4530
4531 bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) {
4532 bool chained = false;
4533 // signal-chaining
4534 if (UseSignalChaining) {
4535 struct sigaction *actp = get_chained_signal_action(sig);
4536 if (actp != NULL) {
4537 chained = call_chained_handler(actp, sig, siginfo, context);
4538 }
4539 }
4540 return chained;
4541 }
4542
4543 // for diagnostic
4544 int sigflags[NSIG];
4545
4546 int os::Linux::get_our_sigflags(int sig) {
4547 assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
4548 return sigflags[sig];
4549 }
4550
4551 void os::Linux::set_our_sigflags(int sig, int flags) {
4552 assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
4553 if (sig > 0 && sig < NSIG) {
4554 sigflags[sig] = flags;
4555 }
4556 }
4557
4558 void os::Linux::set_signal_handler(int sig, bool set_installed) {
4559 // Check for overwrite.
4560 struct sigaction oldAct;
4561 sigaction(sig, (struct sigaction*)NULL, &oldAct);
4562
4563 void* oldhand = oldAct.sa_sigaction
4564 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
4565 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
4566 if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
4567 oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
4568 oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) {
4569 if (AllowUserSignalHandlers || !set_installed) {
4570 // Do not overwrite; user takes responsibility to forward to us.
4571 return;
4572 } else if (UseSignalChaining) {
4573 // save the old handler in jvm
4574 os::Posix::save_preinstalled_handler(sig, oldAct);
4575 // libjsig also interposes the sigaction() call below and saves the
4576 // old sigaction on it own.
4577 } else {
4578 fatal("Encountered unexpected pre-existing sigaction handler "
4579 "%#lx for signal %d.", (long)oldhand, sig);
4580 }
4581 }
4582
4583 struct sigaction sigAct;
4584 sigfillset(&(sigAct.sa_mask));
4585 sigAct.sa_handler = SIG_DFL;
4586 if (!set_installed) {
4587 sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
4588 } else {
4589 sigAct.sa_sigaction = signalHandler;
4590 sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
4591 }
4592 // Save flags, which are set by ours
4593 assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
4594 sigflags[sig] = sigAct.sa_flags;
|