< prev index next >

src/hotspot/os/linux/os_linux.cpp

Print this page




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;


< prev index next >