Path: blob/master/src/hotspot/os/posix/signals_posix.cpp
64440 views
/*1* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"2526#include "jvm.h"27#include "logging/log.hpp"28#include "runtime/atomic.hpp"29#include "runtime/globals.hpp"30#include "runtime/interfaceSupport.inline.hpp"31#include "runtime/java.hpp"32#include "runtime/os.hpp"33#include "runtime/osThread.hpp"34#include "runtime/semaphore.inline.hpp"35#include "runtime/stubRoutines.hpp"36#include "runtime/thread.hpp"37#include "signals_posix.hpp"38#include "utilities/events.hpp"39#include "utilities/ostream.hpp"40#include "utilities/vmError.hpp"4142#include "code/codeCache.hpp"43#include <sys/mman.h>4445#ifdef ZERO46// See stubGenerator_zero.cpp47#include <setjmp.h>48extern sigjmp_buf* get_jmp_buf_for_continuation();49#endif5051#include <signal.h>525354static const char* get_signal_name(int sig, char* out, size_t outlen);5556// Returns address of a handler associated with the given sigaction57static address get_signal_handler(const struct sigaction* action);5859#define HANDLER_IS(handler, address) ((handler) == CAST_FROM_FN_PTR(void*, (address)))60#define HANDLER_IS_IGN(handler) (HANDLER_IS(handler, SIG_IGN))61#define HANDLER_IS_DFL(handler) (HANDLER_IS(handler, SIG_DFL))62#define HANDLER_IS_IGN_OR_DFL(handler) (HANDLER_IS_IGN(handler) || HANDLER_IS_DFL(handler))6364// Various signal related mechanism are laid out in the following order:65//66// sun.misc.Signal67// signal chaining68// signal handling (except suspend/resume)69// suspend/resume7071// Helper function to strip any flags from a sigaction sa_flag72// which are not needed for semantic comparison (see remarks below73// about SA_RESTORER on Linux).74// Also to work around the fact that not all platforms define sa_flags75// as signed int (looking at you, zlinux).76static int get_sanitized_sa_flags(const struct sigaction* sa) {77int f = (int) sa->sa_flags;78#ifdef LINUX79// Glibc on Linux uses the SA_RESTORER flag to indicate80// the use of a "signal trampoline". We have no interest81// in this flag and need to ignore it when checking our82// own flag settings.83// Note: SA_RESTORER is not exposed through signal.h so we84// have to hardcode its 0x04000000 value here.85const int sa_restorer_flag = 0x04000000;86f &= ~sa_restorer_flag;87#endif // LINUX88return f;89}9091// Todo: provide a os::get_max_process_id() or similar. Number of processes92// may have been configured, can be read more accurately from proc fs etc.93#ifndef MAX_PID94#define MAX_PID INT_MAX95#endif96#define IS_VALID_PID(p) (p > 0 && p < MAX_PID)9798#define NUM_IMPORTANT_SIGS 3299100extern "C" {101typedef void (*sa_handler_t)(int);102typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);103}104105// At various places we store handler information for each installed handler.106// SavedSignalHandlers is a helper class for those cases, keeping an array of sigaction107// structures.108class SavedSignalHandlers {109// Note: NSIG can be largish, depending on platform, and this array is expected110// to be sparsely populated. To save space the contained structures are111// C-heap allocated. Since they only get added outside of signal handling112// this is no problem.113struct sigaction* _sa[NSIG];114115bool check_signal_number(int sig) const {116assert(sig > 0 && sig < NSIG, "invalid signal number %d", sig);117return sig > 0 && sig < NSIG;118}119120public:121122SavedSignalHandlers() {123::memset(_sa, 0, sizeof(_sa));124}125126~SavedSignalHandlers() {127for (int i = 0; i < NSIG; i ++) {128FREE_C_HEAP_OBJ(_sa[i]);129}130}131132void set(int sig, const struct sigaction* act) {133if (check_signal_number(sig)) {134assert(_sa[sig] == NULL, "Overwriting signal handler?");135_sa[sig] = NEW_C_HEAP_OBJ(struct sigaction, mtInternal);136*_sa[sig] = *act;137}138}139140const struct sigaction* get(int sig) const {141if (check_signal_number(sig)) {142return _sa[sig];143}144return NULL;145}146};147148149debug_only(static bool signal_sets_initialized = false);150static sigset_t unblocked_sigs, vm_sigs, preinstalled_sigs;151152// Our own signal handlers should never ever get replaced by a third party one.153// To check that, and to aid with diagnostics, store a copy of the handler setup154// and compare it periodically against reality (see os::run_periodic_checks()).155static bool check_signals = true;156static SavedSignalHandlers vm_handlers;157static bool do_check_signal_periodically[NSIG] = { 0 };158159// For signal-chaining:160// if chaining is active, chained_handlers contains all handlers which we161// replaced with our own and to which we must delegate.162static SavedSignalHandlers chained_handlers;163static bool libjsig_is_loaded = false;164typedef struct sigaction *(*get_signal_t)(int);165static get_signal_t get_signal_action = NULL;166167// suspend/resume support168#if defined(__APPLE__)169static OSXSemaphore sr_semaphore;170#else171static PosixSemaphore sr_semaphore;172#endif173174// Signal number used to suspend/resume a thread175// do not use any signal number less than SIGSEGV, see 4355769176int PosixSignals::SR_signum = SIGUSR2;177178// sun.misc.Signal support179static Semaphore* sig_semaphore = NULL;180// a counter for each possible signal value181static volatile jint pending_signals[NSIG+1] = { 0 };182183static const struct {184int sig; const char* name;185} g_signal_info[] = {186{ SIGABRT, "SIGABRT" },187#ifdef SIGAIO188{ SIGAIO, "SIGAIO" },189#endif190{ SIGALRM, "SIGALRM" },191#ifdef SIGALRM1192{ SIGALRM1, "SIGALRM1" },193#endif194{ SIGBUS, "SIGBUS" },195#ifdef SIGCANCEL196{ SIGCANCEL, "SIGCANCEL" },197#endif198{ SIGCHLD, "SIGCHLD" },199#ifdef SIGCLD200{ SIGCLD, "SIGCLD" },201#endif202{ SIGCONT, "SIGCONT" },203#ifdef SIGCPUFAIL204{ SIGCPUFAIL, "SIGCPUFAIL" },205#endif206#ifdef SIGDANGER207{ SIGDANGER, "SIGDANGER" },208#endif209#ifdef SIGDIL210{ SIGDIL, "SIGDIL" },211#endif212#ifdef SIGEMT213{ SIGEMT, "SIGEMT" },214#endif215{ SIGFPE, "SIGFPE" },216#ifdef SIGFREEZE217{ SIGFREEZE, "SIGFREEZE" },218#endif219#ifdef SIGGFAULT220{ SIGGFAULT, "SIGGFAULT" },221#endif222#ifdef SIGGRANT223{ SIGGRANT, "SIGGRANT" },224#endif225{ SIGHUP, "SIGHUP" },226{ SIGILL, "SIGILL" },227#ifdef SIGINFO228{ SIGINFO, "SIGINFO" },229#endif230{ SIGINT, "SIGINT" },231#ifdef SIGIO232{ SIGIO, "SIGIO" },233#endif234#ifdef SIGIOINT235{ SIGIOINT, "SIGIOINT" },236#endif237#ifdef SIGIOT238// SIGIOT is there for BSD compatibility, but on most Unices just a239// synonym for SIGABRT. The result should be "SIGABRT", not240// "SIGIOT".241#if (SIGIOT != SIGABRT )242{ SIGIOT, "SIGIOT" },243#endif244#endif245#ifdef SIGKAP246{ SIGKAP, "SIGKAP" },247#endif248{ SIGKILL, "SIGKILL" },249#ifdef SIGLOST250{ SIGLOST, "SIGLOST" },251#endif252#ifdef SIGLWP253{ SIGLWP, "SIGLWP" },254#endif255#ifdef SIGLWPTIMER256{ SIGLWPTIMER, "SIGLWPTIMER" },257#endif258#ifdef SIGMIGRATE259{ SIGMIGRATE, "SIGMIGRATE" },260#endif261#ifdef SIGMSG262{ SIGMSG, "SIGMSG" },263#endif264{ SIGPIPE, "SIGPIPE" },265#ifdef SIGPOLL266{ SIGPOLL, "SIGPOLL" },267#endif268#ifdef SIGPRE269{ SIGPRE, "SIGPRE" },270#endif271{ SIGPROF, "SIGPROF" },272#ifdef SIGPTY273{ SIGPTY, "SIGPTY" },274#endif275#ifdef SIGPWR276{ SIGPWR, "SIGPWR" },277#endif278{ SIGQUIT, "SIGQUIT" },279#ifdef SIGRECONFIG280{ SIGRECONFIG, "SIGRECONFIG" },281#endif282#ifdef SIGRECOVERY283{ SIGRECOVERY, "SIGRECOVERY" },284#endif285#ifdef SIGRESERVE286{ SIGRESERVE, "SIGRESERVE" },287#endif288#ifdef SIGRETRACT289{ SIGRETRACT, "SIGRETRACT" },290#endif291#ifdef SIGSAK292{ SIGSAK, "SIGSAK" },293#endif294{ SIGSEGV, "SIGSEGV" },295#ifdef SIGSOUND296{ SIGSOUND, "SIGSOUND" },297#endif298#ifdef SIGSTKFLT299{ SIGSTKFLT, "SIGSTKFLT" },300#endif301{ SIGSTOP, "SIGSTOP" },302{ SIGSYS, "SIGSYS" },303#ifdef SIGSYSERROR304{ SIGSYSERROR, "SIGSYSERROR" },305#endif306#ifdef SIGTALRM307{ SIGTALRM, "SIGTALRM" },308#endif309{ SIGTERM, "SIGTERM" },310#ifdef SIGTHAW311{ SIGTHAW, "SIGTHAW" },312#endif313{ SIGTRAP, "SIGTRAP" },314#ifdef SIGTSTP315{ SIGTSTP, "SIGTSTP" },316#endif317{ SIGTTIN, "SIGTTIN" },318{ SIGTTOU, "SIGTTOU" },319#ifdef SIGURG320{ SIGURG, "SIGURG" },321#endif322{ SIGUSR1, "SIGUSR1" },323{ SIGUSR2, "SIGUSR2" },324#ifdef SIGVIRT325{ SIGVIRT, "SIGVIRT" },326#endif327{ SIGVTALRM, "SIGVTALRM" },328#ifdef SIGWAITING329{ SIGWAITING, "SIGWAITING" },330#endif331#ifdef SIGWINCH332{ SIGWINCH, "SIGWINCH" },333#endif334#ifdef SIGWINDOW335{ SIGWINDOW, "SIGWINDOW" },336#endif337{ SIGXCPU, "SIGXCPU" },338{ SIGXFSZ, "SIGXFSZ" },339#ifdef SIGXRES340{ SIGXRES, "SIGXRES" },341#endif342{ -1, NULL }343};344345////////////////////////////////////////////////////////////////////////////////346// sun.misc.Signal support347348void jdk_misc_signal_init() {349// Initialize signal structures350::memset((void*)pending_signals, 0, sizeof(pending_signals));351352// Initialize signal semaphore353sig_semaphore = new Semaphore();354}355356void os::signal_notify(int sig) {357if (sig_semaphore != NULL) {358Atomic::inc(&pending_signals[sig]);359sig_semaphore->signal();360} else {361// Signal thread is not created with ReduceSignalUsage and jdk_misc_signal_init362// initialization isn't called.363assert(ReduceSignalUsage, "signal semaphore should be created");364}365}366367static int check_pending_signals() {368for (;;) {369for (int i = 0; i < NSIG + 1; i++) {370jint n = pending_signals[i];371if (n > 0 && n == Atomic::cmpxchg(&pending_signals[i], n, n - 1)) {372return i;373}374}375sig_semaphore->wait_with_safepoint_check(JavaThread::current());376}377ShouldNotReachHere();378return 0; // Satisfy compiler379}380381int os::signal_wait() {382return check_pending_signals();383}384385////////////////////////////////////////////////////////////////////////////////386// signal chaining support387388struct sigaction* get_chained_signal_action(int sig) {389struct sigaction *actp = NULL;390391if (libjsig_is_loaded) {392// Retrieve the old signal handler from libjsig393actp = (*get_signal_action)(sig);394}395if (actp == NULL) {396// Retrieve the preinstalled signal handler from jvm397actp = const_cast<struct sigaction*>(chained_handlers.get(sig));398}399400return actp;401}402403static bool call_chained_handler(struct sigaction *actp, int sig,404siginfo_t *siginfo, void *context) {405// Call the old signal handler406if (actp->sa_handler == SIG_DFL) {407// It's more reasonable to let jvm treat it as an unexpected exception408// instead of taking the default action.409return false;410} else if (actp->sa_handler != SIG_IGN) {411if ((actp->sa_flags & SA_NODEFER) == 0) {412// automaticlly block the signal413sigaddset(&(actp->sa_mask), sig);414}415416sa_handler_t hand = NULL;417sa_sigaction_t sa = NULL;418bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;419// retrieve the chained handler420if (siginfo_flag_set) {421sa = actp->sa_sigaction;422} else {423hand = actp->sa_handler;424}425426if ((actp->sa_flags & SA_RESETHAND) != 0) {427actp->sa_handler = SIG_DFL;428}429430// try to honor the signal mask431sigset_t oset;432sigemptyset(&oset);433pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);434435// call into the chained handler436if (siginfo_flag_set) {437(*sa)(sig, siginfo, context);438} else {439(*hand)(sig);440}441442// restore the signal mask443pthread_sigmask(SIG_SETMASK, &oset, NULL);444}445// Tell jvm's signal handler the signal is taken care of.446return true;447}448449bool PosixSignals::chained_handler(int sig, siginfo_t* siginfo, void* context) {450bool chained = false;451// signal-chaining452if (UseSignalChaining) {453struct sigaction *actp = get_chained_signal_action(sig);454if (actp != NULL) {455chained = call_chained_handler(actp, sig, siginfo, context);456}457}458return chained;459}460461///// Synchronous (non-deferrable) error signals (ILL, SEGV, FPE, BUS, TRAP):462463// These signals are special because they cannot be deferred and, if they464// happen while delivery is blocked for the receiving thread, will cause UB465// (in practice typically resulting in sudden process deaths or hangs, see466// JDK-8252533). So we must take care never to block them when we cannot be467// absolutely sure they won't happen. In practice, this is always.468//469// Relevant Posix quote:470// "The behavior of a process is undefined after it ignores a SIGFPE, SIGILL,471// SIGSEGV, or SIGBUS signal that was not generated by kill(), sigqueue(), or472// raise()."473//474// We also include SIGTRAP in that list of never-to-block-signals. While not475// mentioned by the Posix documentation, in our (SAPs) experience blocking it476// causes similar problems. Beside, during normal operation - outside of error477// handling - SIGTRAP may be used for implicit NULL checking, so it makes sense478// to never block it.479//480// We deal with those signals in two ways:481// - we just never explicitly block them, which includes not accidentally blocking482// them via sa_mask when establishing signal handlers.483// - as an additional safety measure, at the entrance of a signal handler, we484// unblock them explicitly.485486static void add_error_signals_to_set(sigset_t* set) {487sigaddset(set, SIGILL);488sigaddset(set, SIGBUS);489sigaddset(set, SIGFPE);490sigaddset(set, SIGSEGV);491sigaddset(set, SIGTRAP);492}493494static void remove_error_signals_from_set(sigset_t* set) {495sigdelset(set, SIGILL);496sigdelset(set, SIGBUS);497sigdelset(set, SIGFPE);498sigdelset(set, SIGSEGV);499sigdelset(set, SIGTRAP);500}501502// Unblock all signals whose delivery cannot be deferred and which, if they happen503// while delivery is blocked, would cause crashes or hangs (JDK-8252533).504void PosixSignals::unblock_error_signals() {505sigset_t set;506sigemptyset(&set);507add_error_signals_to_set(&set);508::pthread_sigmask(SIG_UNBLOCK, &set, NULL);509}510511class ErrnoPreserver: public StackObj {512const int _saved;513public:514ErrnoPreserver() : _saved(errno) {}515~ErrnoPreserver() { errno = _saved; }516};517518////////////////////////////////////////////////////////////////////////////////519// JVM_handle_(linux|aix|bsd)_signal()520521// This routine is the shared part of the central hotspot signal handler. It can522// also be called by a user application, if a user application prefers to do523// signal handling itself - in that case it needs to pass signals the VM524// internally uses on to the VM first.525//526// The user-defined signal handler must pass unrecognized signals to this527// routine, and if it returns true (non-zero), then the signal handler must528// return immediately. If the flag "abort_if_unrecognized" is true, then this529// routine will never return false (zero), but instead will execute a VM panic530// routine to kill the process.531//532// If this routine returns false, it is OK to call it again. This allows533// the user-defined signal handler to perform checks either before or after534// the VM performs its own checks. Naturally, the user code would be making535// a serious error if it tried to handle an exception (such as a null check536// or breakpoint) that the VM was generating for its own correct operation.537//538// This routine may recognize any of the following kinds of signals:539// SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1.540// It should be consulted by handlers for any of those signals.541//542// The caller of this routine must pass in the three arguments supplied543// to the function referred to in the "sa_sigaction" (not the "sa_handler")544// field of the structure passed to sigaction(). This routine assumes that545// the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.546//547// Note that the VM will print warnings if it detects conflicting signal548// handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".549//550551#if defined(BSD)552#define JVM_HANDLE_XXX_SIGNAL JVM_handle_bsd_signal553#elif defined(AIX)554#define JVM_HANDLE_XXX_SIGNAL JVM_handle_aix_signal555#elif defined(LINUX)556#define JVM_HANDLE_XXX_SIGNAL JVM_handle_linux_signal557#else558#error who are you?559#endif560561extern "C" JNIEXPORT562int JVM_HANDLE_XXX_SIGNAL(int sig, siginfo_t* info,563void* ucVoid, int abort_if_unrecognized)564{565assert(info != NULL && ucVoid != NULL, "sanity");566567if (sig == BREAK_SIGNAL) {568assert(!ReduceSignalUsage, "Should not happen with -Xrs/-XX:+ReduceSignalUsage");569return true; // ignore it570}571572// Note: it's not uncommon that JNI code uses signal/sigset to install,573// then restore certain signal handler (e.g. to temporarily block SIGPIPE,574// or have a SIGILL handler when detecting CPU type). When that happens,575// this handler might be invoked with junk info/ucVoid. To avoid unnecessary576// crash when libjsig is not preloaded, try handle signals that do not require577// siginfo/ucontext first.578579// Preserve errno value over signal handler.580// (note: RAII ok here, even with JFR thread crash protection, see below).581ErrnoPreserver ep;582583// Unblock all synchronous error signals (see JDK-8252533)584PosixSignals::unblock_error_signals();585586ucontext_t* const uc = (ucontext_t*) ucVoid;587Thread* const t = Thread::current_or_null_safe();588589// Hopefully placing W^X handing here is safe enough, maybe check repeat?590if (!os::Bsd::isRWXJITAvailable() && sig == SIGBUS) {591address pc = (address) os::Posix::ucontext_get_pc(uc);592//static address last_pc, last_si_addr;593if (pc == info->si_addr) { //(pc >= CodeCache::low_bound() && pc < CodeCache::high_bound()) {594//(CodeCache::contains(pc) || thread->thread_state() == _thread_in_Java) {595//if (last_pc != pc) {596// last_pc = pc;597bool handled = !mprotect((address) ((uintptr_t)pc & -PAGE_SIZE), PAGE_SIZE, PROT_READ | PROT_EXEC);598if (handled) return true;599//}600} else if (info->si_addr >= CodeCache::low_bound() && info->si_addr < CodeCache::high_bound()) {601//(CodeCache::contains(info->si_addr)) { // && last_si_addr != info->si_addr) {602//last_si_addr = (address) info->si_addr;603bool handled = !mprotect((address) ((uintptr_t)info->si_addr & -PAGE_SIZE), PAGE_SIZE, PROT_READ | PROT_WRITE);604if (handled) return true;605}606}607608609// Handle JFR thread crash protection.610// Note: this may cause us to longjmp away. Do not use any code before this611// point which really needs any form of epilogue code running, eg RAII objects.612os::ThreadCrashProtection::check_crash_protection(sig, t);613614bool signal_was_handled = false;615616// Handle assertion poison page accesses.617#ifdef CAN_SHOW_REGISTERS_ON_ASSERT618if (!signal_was_handled &&619((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison)) {620signal_was_handled = handle_assert_poison_fault(ucVoid, info->si_addr);621}622#endif623624if (!signal_was_handled) {625// Handle SafeFetch access.626#ifndef ZERO627if (uc != NULL) {628address pc = os::Posix::ucontext_get_pc(uc);629if (StubRoutines::is_safefetch_fault(pc)) {630os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));631signal_was_handled = true;632}633}634#else635// See JDK-8076185636if (sig == SIGSEGV || sig == SIGBUS) {637sigjmp_buf* const pjb = get_jmp_buf_for_continuation();638if (pjb) {639siglongjmp(*pjb, 1);640}641}642#endif // ZERO643}644645// Ignore SIGPIPE and SIGXFSZ (4229104, 6499219).646if (!signal_was_handled &&647(sig == SIGPIPE || sig == SIGXFSZ)) {648PosixSignals::chained_handler(sig, info, ucVoid);649signal_was_handled = true; // unconditionally.650}651652// Call platform dependent signal handler.653if (!signal_was_handled) {654JavaThread* const jt = (t != NULL && t->is_Java_thread()) ? (JavaThread*) t : NULL;655signal_was_handled = PosixSignals::pd_hotspot_signal_handler(sig, info, uc, jt);656}657658// From here on, if the signal had not been handled, it is a fatal error.659660// Give the chained signal handler - should it exist - a shot.661if (!signal_was_handled) {662signal_was_handled = PosixSignals::chained_handler(sig, info, ucVoid);663}664665// Invoke fatal error handling.666if (!signal_was_handled && abort_if_unrecognized) {667// Extract pc from context for the error handler to display.668address pc = NULL;669if (uc != NULL) {670// prepare fault pc address for error reporting.671if (S390_ONLY(sig == SIGILL || sig == SIGFPE) NOT_S390(false)) {672pc = (address)info->si_addr;673} else if (ZERO_ONLY(true) NOT_ZERO(false)) {674// Non-arch-specific Zero code does not really know the pc.675// This can be alleviated by making arch-specific os::Posix::ucontext_get_pc676// available for Zero for known architectures. But for generic Zero677// code, it would still remain unknown.678pc = NULL;679} else {680pc = os::Posix::ucontext_get_pc(uc);681}682}683// For Zero, we ignore the crash context, because:684// a) The crash would be in C++ interpreter code, so context is not really relevant;685// b) Generic Zero code would not be able to parse it, so when generic error686// reporting code asks e.g. about frames on stack, Zero would experience687// a secondary ShouldNotCallThis() crash.688VMError::report_and_die(t, sig, pc, info, NOT_ZERO(ucVoid) ZERO_ONLY(NULL));689// VMError should not return.690ShouldNotReachHere();691}692return signal_was_handled;693}694695// Entry point for the hotspot signal handler.696static void javaSignalHandler(int sig, siginfo_t* info, void* ucVoid) {697// Do not add any code here!698// Only add code to either JVM_HANDLE_XXX_SIGNAL or PosixSignals::pd_hotspot_signal_handler.699(void)JVM_HANDLE_XXX_SIGNAL(sig, info, ucVoid, true);700}701702static void UserHandler(int sig, void *siginfo, void *context) {703704PosixSignals::unblock_error_signals();705706// Ctrl-C is pressed during error reporting, likely because the error707// handler fails to abort. Let VM die immediately.708if (sig == SIGINT && VMError::is_error_reported()) {709os::die();710}711712os::signal_notify(sig);713}714715static void print_signal_handler_name(outputStream* os, address handler, char* buf, size_t buflen) {716// We demangle, but omit arguments - signal handlers should have always the same prototype.717os::print_function_and_library_name(os, handler, buf, buflen,718true, // shorten_path719true, // demangle720true // omit arguments721);722}723724// Writes one-line description of a combination of sigaction.sa_flags into a user725// provided buffer. Returns that buffer.726static const char* describe_sa_flags(int flags, char* buffer, size_t size) {727char* p = buffer;728size_t remaining = size;729bool first = true;730int idx = 0;731732assert(buffer, "invalid argument");733734if (size == 0) {735return buffer;736}737738strncpy(buffer, "none", size);739740const unsigned int unknown_flag = ~(SA_NOCLDSTOP |741SA_ONSTACK |742SA_NOCLDSTOP |743SA_RESTART |744SA_SIGINFO |745SA_NOCLDWAIT |746SA_NODEFER747AIX_ONLY(| SA_OLDSTYLE)748);749750const struct {751// NB: i is an unsigned int here because SA_RESETHAND is on some752// systems 0x80000000, which is implicitly unsigned. Assigning753// it to an int field would be an overflow in unsigned-to-signed754// conversion.755unsigned int i;756const char* s;757} flaginfo [] = {758{ SA_NOCLDSTOP, "SA_NOCLDSTOP" },759{ SA_ONSTACK, "SA_ONSTACK" },760{ SA_RESETHAND, "SA_RESETHAND" },761{ SA_RESTART, "SA_RESTART" },762{ SA_SIGINFO, "SA_SIGINFO" },763{ SA_NOCLDWAIT, "SA_NOCLDWAIT" },764{ SA_NODEFER, "SA_NODEFER" },765#if defined(AIX)766{ SA_OLDSTYLE, "SA_OLDSTYLE" },767#endif768{ unknown_flag, "NOT USED" }769};770771for (idx = 0; flaginfo[idx].i != unknown_flag && remaining > 1; idx++) {772if (flags & flaginfo[idx].i) {773if (first) {774jio_snprintf(p, remaining, "%s", flaginfo[idx].s);775first = false;776} else {777jio_snprintf(p, remaining, "|%s", flaginfo[idx].s);778}779const size_t len = strlen(p);780p += len;781remaining -= len;782}783}784unsigned int unknowns = flags & unknown_flag;785if (unknowns != 0) {786jio_snprintf(p, remaining, "|Unknown_flags:%x", unknowns);787}788789buffer[size - 1] = '\0';790791return buffer;792}793794// Prints one-line description of a combination of sigaction.sa_flags.795static void print_sa_flags(outputStream* st, int flags) {796char buffer[0x100];797describe_sa_flags(flags, buffer, sizeof(buffer));798st->print("%s", buffer);799}800801// Implementation may use the same storage for both the sa_sigaction field and the sa_handler field,802// so check for "sigAct.sa_flags == SA_SIGINFO"803static address get_signal_handler(const struct sigaction* action) {804bool siginfo_flag_set = (action->sa_flags & SA_SIGINFO) != 0;805if (siginfo_flag_set) {806return CAST_FROM_FN_PTR(address, action->sa_sigaction);807} else {808return CAST_FROM_FN_PTR(address, action->sa_handler);809}810}811812typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);813814static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context);815816// Semantically compare two sigaction structures. Return true if they are referring to817// the same handler, using the same flags.818static bool are_handlers_equal(const struct sigaction* sa,819const struct sigaction* expected_sa) {820address this_handler = get_signal_handler(sa);821address expected_handler = get_signal_handler(expected_sa);822const int this_flags = get_sanitized_sa_flags(sa);823const int expected_flags = get_sanitized_sa_flags(expected_sa);824return (this_handler == expected_handler) &&825(this_flags == expected_flags);826}827828// If we installed one of our signal handlers for sig, check that the current829// setup matches what we originally installed.830static void check_signal_handler(int sig) {831char buf[O_BUFLEN];832bool mismatch = false;833834if (!do_check_signal_periodically[sig]) {835return;836}837838const struct sigaction* expected_act = vm_handlers.get(sig);839assert(expected_act != NULL, "Sanity");840841// Retrieve current signal setup.842struct sigaction act;843static os_sigaction_t os_sigaction = NULL;844if (os_sigaction == NULL) {845// only trust the default sigaction, in case it has been interposed846os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");847if (os_sigaction == NULL) return;848}849850os_sigaction(sig, (struct sigaction*)NULL, &act);851852// Compare both sigaction structures (intelligently; only the members we care about).853if (!are_handlers_equal(&act, expected_act)) {854tty->print_cr("Warning: %s handler modified!", os::exception_name(sig, buf, sizeof(buf)));855// If we had a mismatch:856// - print all signal handlers. As part of that printout, details will be printed857// about any modified handlers.858// - Disable any further checks for this signal - we do not want to flood stdout. Though859// depending on which signal had been overwritten, we may die very soon anyway.860os::print_signal_handlers(tty, buf, O_BUFLEN);861do_check_signal_periodically[sig] = false;862tty->print_cr("Consider using jsig library.");863// Running under non-interactive shell, SHUTDOWN2_SIGNAL will be reassigned SIG_IGN864if (sig == SHUTDOWN2_SIGNAL && !isatty(fileno(stdin))) {865tty->print_cr("Note: Running in non-interactive shell, %s handler is replaced by shell",866os::exception_name(sig, buf, O_BUFLEN));867}868}869}870871void* os::user_handler() {872return CAST_FROM_FN_PTR(void*, UserHandler);873}874875void* os::signal(int signal_number, void* handler) {876struct sigaction sigAct, oldSigAct;877878sigfillset(&(sigAct.sa_mask));879remove_error_signals_from_set(&(sigAct.sa_mask));880881sigAct.sa_flags = SA_RESTART|SA_SIGINFO;882sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);883884if (sigaction(signal_number, &sigAct, &oldSigAct)) {885// -1 means registration failed886return (void *)-1;887}888889return get_signal_handler(&oldSigAct);890}891892void os::signal_raise(int signal_number) {893::raise(signal_number);894}895896// Will be modified when max signal is changed to be dynamic897int os::sigexitnum_pd() {898return NSIG;899}900901// This method is a periodic task to check for misbehaving JNI applications902// under CheckJNI, we can add any periodic checks here903void os::run_periodic_checks() {904905if (check_signals == false) return;906907// SEGV and BUS if overridden could potentially prevent908// generation of hs*.log in the event of a crash, debugging909// such a case can be very challenging, so we absolutely910// check the following for a good measure:911check_signal_handler(SIGSEGV);912check_signal_handler(SIGILL);913check_signal_handler(SIGFPE);914check_signal_handler(SIGBUS);915check_signal_handler(SIGPIPE);916check_signal_handler(SIGXFSZ);917PPC64_ONLY(check_signal_handler(SIGTRAP);)918919// ReduceSignalUsage allows the user to override these handlers920// see comments at the very top and jvm_md.h921if (!ReduceSignalUsage) {922check_signal_handler(SHUTDOWN1_SIGNAL);923check_signal_handler(SHUTDOWN2_SIGNAL);924check_signal_handler(SHUTDOWN3_SIGNAL);925check_signal_handler(BREAK_SIGNAL);926}927928check_signal_handler(PosixSignals::SR_signum);929}930931// Helper function for PosixSignals::print_siginfo_...():932// return a textual description for signal code.933struct enum_sigcode_desc_t {934const char* s_name;935const char* s_desc;936};937938static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t* out) {939940const struct {941int sig; int code; const char* s_code; const char* s_desc;942} t1 [] = {943{ SIGILL, ILL_ILLOPC, "ILL_ILLOPC", "Illegal opcode." },944{ SIGILL, ILL_ILLOPN, "ILL_ILLOPN", "Illegal operand." },945{ SIGILL, ILL_ILLADR, "ILL_ILLADR", "Illegal addressing mode." },946{ SIGILL, ILL_ILLTRP, "ILL_ILLTRP", "Illegal trap." },947{ SIGILL, ILL_PRVOPC, "ILL_PRVOPC", "Privileged opcode." },948{ SIGILL, ILL_PRVREG, "ILL_PRVREG", "Privileged register." },949{ SIGILL, ILL_COPROC, "ILL_COPROC", "Coprocessor error." },950{ SIGILL, ILL_BADSTK, "ILL_BADSTK", "Internal stack error." },951#if defined(IA64) && defined(LINUX)952{ SIGILL, ILL_BADIADDR, "ILL_BADIADDR", "Unimplemented instruction address" },953{ SIGILL, ILL_BREAK, "ILL_BREAK", "Application Break instruction" },954#endif955{ SIGFPE, FPE_INTDIV, "FPE_INTDIV", "Integer divide by zero." },956{ SIGFPE, FPE_INTOVF, "FPE_INTOVF", "Integer overflow." },957{ SIGFPE, FPE_FLTDIV, "FPE_FLTDIV", "Floating-point divide by zero." },958{ SIGFPE, FPE_FLTOVF, "FPE_FLTOVF", "Floating-point overflow." },959{ SIGFPE, FPE_FLTUND, "FPE_FLTUND", "Floating-point underflow." },960{ SIGFPE, FPE_FLTRES, "FPE_FLTRES", "Floating-point inexact result." },961{ SIGFPE, FPE_FLTINV, "FPE_FLTINV", "Invalid floating-point operation." },962{ SIGFPE, FPE_FLTSUB, "FPE_FLTSUB", "Subscript out of range." },963{ SIGSEGV, SEGV_MAPERR, "SEGV_MAPERR", "Address not mapped to object." },964{ SIGSEGV, SEGV_ACCERR, "SEGV_ACCERR", "Invalid permissions for mapped object." },965#if defined(AIX)966// no explanation found what keyerr would be967{ SIGSEGV, SEGV_KEYERR, "SEGV_KEYERR", "key error" },968#endif969#if defined(IA64) && !defined(AIX)970{ SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" },971#endif972{ SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." },973{ SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." },974{ SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." },975{ SIGTRAP, TRAP_BRKPT, "TRAP_BRKPT", "Process breakpoint." },976{ SIGTRAP, TRAP_TRACE, "TRAP_TRACE", "Process trace trap." },977{ SIGCHLD, CLD_EXITED, "CLD_EXITED", "Child has exited." },978{ SIGCHLD, CLD_KILLED, "CLD_KILLED", "Child has terminated abnormally and did not create a core file." },979{ SIGCHLD, CLD_DUMPED, "CLD_DUMPED", "Child has terminated abnormally and created a core file." },980{ SIGCHLD, CLD_TRAPPED, "CLD_TRAPPED", "Traced child has trapped." },981{ SIGCHLD, CLD_STOPPED, "CLD_STOPPED", "Child has stopped." },982{ SIGCHLD, CLD_CONTINUED,"CLD_CONTINUED","Stopped child has continued." },983#ifdef SIGPOLL984{ SIGPOLL, POLL_OUT, "POLL_OUT", "Output buffers available." },985{ SIGPOLL, POLL_MSG, "POLL_MSG", "Input message available." },986{ SIGPOLL, POLL_ERR, "POLL_ERR", "I/O error." },987{ SIGPOLL, POLL_PRI, "POLL_PRI", "High priority input available." },988{ SIGPOLL, POLL_HUP, "POLL_HUP", "Device disconnected. [Option End]" },989#endif990{ -1, -1, NULL, NULL }991};992993// Codes valid in any signal context.994const struct {995int code; const char* s_code; const char* s_desc;996} t2 [] = {997{ SI_USER, "SI_USER", "Signal sent by kill()." },998{ SI_QUEUE, "SI_QUEUE", "Signal sent by the sigqueue()." },999{ SI_TIMER, "SI_TIMER", "Signal generated by expiration of a timer set by timer_settime()." },1000{ SI_ASYNCIO, "SI_ASYNCIO", "Signal generated by completion of an asynchronous I/O request." },1001{ SI_MESGQ, "SI_MESGQ", "Signal generated by arrival of a message on an empty message queue." },1002// Linux specific1003#ifdef SI_TKILL1004{ SI_TKILL, "SI_TKILL", "Signal sent by tkill (pthread_kill)" },1005#endif1006#ifdef SI_DETHREAD1007{ SI_DETHREAD, "SI_DETHREAD", "Signal sent by execve() killing subsidiary threads" },1008#endif1009#ifdef SI_KERNEL1010{ SI_KERNEL, "SI_KERNEL", "Signal sent by kernel." },1011#endif1012#ifdef SI_SIGIO1013{ SI_SIGIO, "SI_SIGIO", "Signal sent by queued SIGIO" },1014#endif10151016#if defined(AIX)1017{ SI_UNDEFINED, "SI_UNDEFINED","siginfo contains partial information" },1018{ SI_EMPTY, "SI_EMPTY", "siginfo contains no useful information" },1019#endif10201021{ -1, NULL, NULL }1022};10231024const char* s_code = NULL;1025const char* s_desc = NULL;10261027for (int i = 0; t1[i].sig != -1; i ++) {1028if (t1[i].sig == si->si_signo && t1[i].code == si->si_code) {1029s_code = t1[i].s_code;1030s_desc = t1[i].s_desc;1031break;1032}1033}10341035if (s_code == NULL) {1036for (int i = 0; t2[i].s_code != NULL; i ++) {1037if (t2[i].code == si->si_code) {1038s_code = t2[i].s_code;1039s_desc = t2[i].s_desc;1040}1041}1042}10431044if (s_code == NULL) {1045out->s_name = "unknown";1046out->s_desc = "unknown";1047return false;1048}10491050out->s_name = s_code;1051out->s_desc = s_desc;10521053return true;1054}10551056bool os::signal_sent_by_kill(const void* siginfo) {1057const siginfo_t* const si = (const siginfo_t*)siginfo;1058return si->si_code == SI_USER || si->si_code == SI_QUEUE1059#ifdef SI_TKILL1060|| si->si_code == SI_TKILL1061#endif1062;1063}10641065// Returns true if signal number is valid.1066static bool is_valid_signal(int sig) {1067// MacOS not really POSIX compliant: sigaddset does not return1068// an error for invalid signal numbers. However, MacOS does not1069// support real time signals and simply seems to have just 331070// signals with no holes in the signal range.1071#if defined(__APPLE__)1072return sig >= 1 && sig < NSIG;1073#else1074// Use sigaddset to check for signal validity.1075sigset_t set;1076sigemptyset(&set);1077if (sigaddset(&set, sig) == -1 && errno == EINVAL) {1078return false;1079}1080return true;1081#endif1082}10831084static const char* get_signal_name(int sig, char* out, size_t outlen) {10851086const char* ret = NULL;10871088#ifdef SIGRTMIN1089if (sig >= SIGRTMIN && sig <= SIGRTMAX) {1090if (sig == SIGRTMIN) {1091ret = "SIGRTMIN";1092} else if (sig == SIGRTMAX) {1093ret = "SIGRTMAX";1094} else {1095jio_snprintf(out, outlen, "SIGRTMIN+%d", sig - SIGRTMIN);1096return out;1097}1098}1099#endif11001101if (sig > 0) {1102for (int idx = 0; g_signal_info[idx].sig != -1; idx ++) {1103if (g_signal_info[idx].sig == sig) {1104ret = g_signal_info[idx].name;1105break;1106}1107}1108}11091110if (!ret) {1111if (!is_valid_signal(sig)) {1112ret = "INVALID";1113} else {1114ret = "UNKNOWN";1115}1116}11171118if (out && outlen > 0) {1119strncpy(out, ret, outlen);1120out[outlen - 1] = '\0';1121}1122return out;1123}11241125void os::print_siginfo(outputStream* os, const void* si0) {11261127const siginfo_t* const si = (const siginfo_t*) si0;11281129char buf[20];1130os->print("siginfo:");11311132if (!si) {1133os->print(" <null>");1134return;1135}11361137const int sig = si->si_signo;11381139os->print(" si_signo: %d (%s)", sig, get_signal_name(sig, buf, sizeof(buf)));11401141enum_sigcode_desc_t ed;1142get_signal_code_description(si, &ed);1143os->print(", si_code: %d (%s)", si->si_code, ed.s_name);11441145if (si->si_errno) {1146os->print(", si_errno: %d", si->si_errno);1147}11481149// Output additional information depending on the signal code.11501151// Note: Many implementations lump si_addr, si_pid, si_uid etc. together as unions,1152// so it depends on the context which member to use. For synchronous error signals,1153// we print si_addr, unless the signal was sent by another process or thread, in1154// which case we print out pid or tid of the sender.1155if (os::signal_sent_by_kill(si)) {1156const pid_t pid = si->si_pid;1157os->print(", si_pid: %ld", (long) pid);1158if (IS_VALID_PID(pid)) {1159const pid_t me = getpid();1160if (me == pid) {1161os->print(" (current process)");1162}1163} else {1164os->print(" (invalid)");1165}1166os->print(", si_uid: %ld", (long) si->si_uid);1167if (sig == SIGCHLD) {1168os->print(", si_status: %d", si->si_status);1169}1170} else if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||1171sig == SIGTRAP || sig == SIGFPE) {1172os->print(", si_addr: " PTR_FORMAT, p2i(si->si_addr));1173#ifdef SIGPOLL1174} else if (sig == SIGPOLL) {1175// siginfo_t.si_band is defined as "long", and it is so in most1176// implementations. But SPARC64 glibc has a bug: si_band is "int".1177// Cast si_band to "long" to prevent format specifier mismatch.1178// See: https://sourceware.org/bugzilla/show_bug.cgi?id=238211179os->print(", si_band: %ld", (long) si->si_band);1180#endif1181}1182}11831184bool os::signal_thread(Thread* thread, int sig, const char* reason) {1185OSThread* osthread = thread->osthread();1186if (osthread) {1187int status = pthread_kill(osthread->pthread_id(), sig);1188if (status == 0) {1189Events::log(Thread::current(), "sent signal %d to Thread " INTPTR_FORMAT " because %s.",1190sig, p2i(thread), reason);1191return true;1192}1193}1194return false;1195}11961197// Returns:1198// NULL for an invalid signal number1199// "SIG<num>" for a valid but unknown signal number1200// signal name otherwise.1201const char* os::exception_name(int sig, char* buf, size_t size) {1202if (!is_valid_signal(sig)) {1203return NULL;1204}1205const char* const name = get_signal_name(sig, buf, size);1206if (strcmp(name, "UNKNOWN") == 0) {1207jio_snprintf(buf, size, "SIG%d", sig);1208}1209return buf;1210}12111212int os::get_signal_number(const char* signal_name) {1213char tmp[30];1214const char* s = signal_name;1215if (s[0] != 'S' || s[1] != 'I' || s[2] != 'G') {1216jio_snprintf(tmp, sizeof(tmp), "SIG%s", signal_name);1217s = tmp;1218}1219for (int idx = 0; g_signal_info[idx].sig != -1; idx ++) {1220if (strcmp(g_signal_info[idx].name, s) == 0) {1221return g_signal_info[idx].sig;1222}1223}1224return -1;1225}12261227void set_signal_handler(int sig, bool do_check = true) {1228// Check for overwrite.1229struct sigaction oldAct;1230sigaction(sig, (struct sigaction*)NULL, &oldAct);12311232// Query the current signal handler. Needs to be a separate operation1233// from installing a new handler since we need to honor AllowUserSignalHandlers.1234void* oldhand = get_signal_handler(&oldAct);1235if (!HANDLER_IS_IGN_OR_DFL(oldhand) &&1236!HANDLER_IS(oldhand, javaSignalHandler)) {1237if (AllowUserSignalHandlers) {1238// Do not overwrite; user takes responsibility to forward to us.1239return;1240} else if (UseSignalChaining) {1241// save the old handler in jvm1242chained_handlers.set(sig, &oldAct);1243// libjsig also interposes the sigaction() call below and saves the1244// old sigaction on it own.1245} else {1246fatal("Encountered unexpected pre-existing sigaction handler "1247"%#lx for signal %d.", (long)oldhand, sig);1248}1249}12501251struct sigaction sigAct;1252sigfillset(&(sigAct.sa_mask));1253remove_error_signals_from_set(&(sigAct.sa_mask));1254sigAct.sa_sigaction = javaSignalHandler;1255sigAct.sa_flags = SA_SIGINFO|SA_RESTART;1256#if defined(__APPLE__)1257// Needed for main thread as XNU (Mac OS X kernel) will only deliver SIGSEGV1258// (which starts as SIGBUS) on main thread with faulting address inside "stack+guard pages"1259// if the signal handler declares it will handle it on alternate stack.1260// Notice we only declare we will handle it on alt stack, but we are not1261// actually going to use real alt stack - this is just a workaround.1262// Please see ux_exception.c, method catch_mach_exception_raise for details1263// link http://www.opensource.apple.com/source/xnu/xnu-2050.18.24/bsd/uxkern/ux_exception.c1264if (sig == SIGSEGV) {1265sigAct.sa_flags |= SA_ONSTACK;1266}1267#endif12681269// Save handler setup for later checking1270vm_handlers.set(sig, &sigAct);1271do_check_signal_periodically[sig] = do_check;12721273int ret = sigaction(sig, &sigAct, &oldAct);1274assert(ret == 0, "check");12751276void* oldhand2 = get_signal_handler(&oldAct);1277assert(oldhand2 == oldhand, "no concurrent signal handler installation");1278}12791280// install signal handlers for signals that HotSpot needs to1281// handle in order to support Java-level exception handling.1282void install_signal_handlers() {1283// signal-chaining1284typedef void (*signal_setting_t)();1285signal_setting_t begin_signal_setting = NULL;1286signal_setting_t end_signal_setting = NULL;1287begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,1288dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));1289if (begin_signal_setting != NULL) {1290end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,1291dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));1292get_signal_action = CAST_TO_FN_PTR(get_signal_t,1293dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));1294libjsig_is_loaded = true;1295assert(UseSignalChaining, "should enable signal-chaining");1296}1297if (libjsig_is_loaded) {1298// Tell libjsig jvm is setting signal handlers1299(*begin_signal_setting)();1300}13011302set_signal_handler(SIGSEGV);1303set_signal_handler(SIGPIPE);1304set_signal_handler(SIGBUS);1305set_signal_handler(SIGILL);1306set_signal_handler(SIGFPE);1307PPC64_ONLY(set_signal_handler(SIGTRAP);)1308set_signal_handler(SIGXFSZ);1309if (!ReduceSignalUsage) {1310// This is just for early initialization phase. Intercepting the signal here reduces the risk1311// that an attach client accidentally forces HotSpot to quit prematurely. We skip the periodic1312// check because late initialization will overwrite it to UserHandler.1313set_signal_handler(BREAK_SIGNAL, false);1314}1315#if defined(__APPLE__)1316// lldb (gdb) installs both standard BSD signal handlers, and mach exception1317// handlers. By replacing the existing task exception handler, we disable lldb's mach1318// exception handling, while leaving the standard BSD signal handlers functional.1319//1320// EXC_MASK_BAD_ACCESS needed by all architectures for NULL ptr checking1321// EXC_MASK_ARITHMETIC needed by all architectures for div by 0 checking1322// EXC_MASK_BAD_INSTRUCTION needed by aarch64 to initiate deoptimization1323kern_return_t kr;1324kr = task_set_exception_ports(mach_task_self(),1325EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC1326AARCH64_ONLY(| EXC_MASK_BAD_INSTRUCTION),1327MACH_PORT_NULL,1328EXCEPTION_STATE_IDENTITY,1329MACHINE_THREAD_STATE);13301331assert(kr == KERN_SUCCESS, "could not set mach task signal handler");1332#endif13331334if (libjsig_is_loaded) {1335// Tell libjsig jvm finishes setting signal handlers1336(*end_signal_setting)();1337}13381339// We don't activate signal checker if libjsig is in place, we trust ourselves1340// and if UserSignalHandler is installed all bets are off.1341// Log that signal checking is off only if -verbose:jni is specified.1342if (CheckJNICalls) {1343if (libjsig_is_loaded) {1344log_debug(jni, resolve)("Info: libjsig is activated, all active signal checking is disabled");1345check_signals = false;1346}1347if (AllowUserSignalHandlers) {1348log_debug(jni, resolve)("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");1349check_signals = false;1350}1351}1352}13531354// Returns one-line short description of a signal set in a user provided buffer.1355static const char* describe_signal_set_short(const sigset_t* set, char* buffer, size_t buf_size) {1356assert(buf_size == (NUM_IMPORTANT_SIGS + 1), "wrong buffer size");1357// Note: for shortness, just print out the first 32. That should1358// cover most of the useful ones, apart from realtime signals.1359for (int sig = 1; sig <= NUM_IMPORTANT_SIGS; sig++) {1360const int rc = sigismember(set, sig);1361if (rc == -1 && errno == EINVAL) {1362buffer[sig-1] = '?';1363} else {1364buffer[sig-1] = rc == 0 ? '0' : '1';1365}1366}1367buffer[NUM_IMPORTANT_SIGS] = 0;1368return buffer;1369}13701371// Prints one-line description of a signal set.1372static void print_signal_set_short(outputStream* st, const sigset_t* set) {1373char buf[NUM_IMPORTANT_SIGS + 1];1374describe_signal_set_short(set, buf, sizeof(buf));1375st->print("%s", buf);1376}13771378static void print_single_signal_handler(outputStream* st,1379const struct sigaction* act,1380char* buf, size_t buflen) {13811382address handler = get_signal_handler(act);1383if (HANDLER_IS_DFL(handler)) {1384st->print("SIG_DFL");1385} else if (HANDLER_IS_IGN(handler)) {1386st->print("SIG_IGN");1387} else {1388print_signal_handler_name(st, handler, buf, buflen);1389}13901391st->print(", mask=");1392print_signal_set_short(st, &(act->sa_mask));13931394st->print(", flags=");1395int flags = get_sanitized_sa_flags(act);1396print_sa_flags(st, flags);13971398}13991400// Print established signal handler for this signal.1401// - if this signal handler was installed by us and is chained to a pre-established user handler1402// it replaced, print that one too.1403// - otherwise, if this signal handler was installed by us and replaced another handler to which we1404// are not chained (e.g. if chaining is off), print that one too.1405void PosixSignals::print_signal_handler(outputStream* st, int sig,1406char* buf, size_t buflen) {14071408st->print("%10s: ", os::exception_name(sig, buf, buflen));14091410struct sigaction current_act;1411sigaction(sig, NULL, ¤t_act);14121413print_single_signal_handler(st, ¤t_act, buf, buflen);1414st->cr();14151416// If we expected to see our own hotspot signal handler but found a different one,1417// print a warning (unless the handler replacing it is our own crash handler, which can1418// happen if this function is called during error reporting).1419const struct sigaction* expected_act = vm_handlers.get(sig);1420if (expected_act != NULL) {1421const address current_handler = get_signal_handler(¤t_act);1422if (!(HANDLER_IS(current_handler, VMError::crash_handler_address))) {1423if (!are_handlers_equal(¤t_act, expected_act)) {1424st->print_cr(" *** Handler was modified!");1425st->print (" *** Expected: ");1426print_single_signal_handler(st, expected_act, buf, buflen);1427st->cr();1428}1429}1430}14311432// If there is a chained handler waiting behind the current one, print it too.1433const struct sigaction* chained_act = get_chained_signal_action(sig);1434if (chained_act != NULL) {1435st->print(" chained to: ");1436print_single_signal_handler(st, ¤t_act, buf, buflen);1437st->cr();1438}1439}14401441void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {1442st->print_cr("Signal Handlers:");1443PosixSignals::print_signal_handler(st, SIGSEGV, buf, buflen);1444PosixSignals::print_signal_handler(st, SIGBUS , buf, buflen);1445PosixSignals::print_signal_handler(st, SIGFPE , buf, buflen);1446PosixSignals::print_signal_handler(st, SIGPIPE, buf, buflen);1447PosixSignals::print_signal_handler(st, SIGXFSZ, buf, buflen);1448PosixSignals::print_signal_handler(st, SIGILL , buf, buflen);1449PosixSignals::print_signal_handler(st, PosixSignals::SR_signum, buf, buflen);1450PosixSignals::print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);1451PosixSignals::print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);1452PosixSignals::print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);1453PosixSignals::print_signal_handler(st, BREAK_SIGNAL, buf, buflen);1454#if defined(SIGDANGER)1455// We also want to know if someone else adds a SIGDANGER handler because1456// that will interfere with OOM killling.1457PosixSignals::print_signal_handler(st, SIGDANGER, buf, buflen);1458#endif1459#if defined(SIGTRAP)1460PosixSignals::print_signal_handler(st, SIGTRAP, buf, buflen);1461#endif1462}14631464bool PosixSignals::is_sig_ignored(int sig) {1465struct sigaction oact;1466sigaction(sig, (struct sigaction*)NULL, &oact);1467if (HANDLER_IS_IGN(get_signal_handler(&oact))) {1468return true;1469} else {1470return false;1471}1472}14731474static void signal_sets_init() {1475sigemptyset(&preinstalled_sigs);14761477// Should also have an assertion stating we are still single-threaded.1478assert(!signal_sets_initialized, "Already initialized");1479// Fill in signals that are necessarily unblocked for all threads in1480// the VM. Currently, we unblock the following signals:1481// SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden1482// by -Xrs (=ReduceSignalUsage));1483// BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all1484// other threads. The "ReduceSignalUsage" boolean tells us not to alter1485// the dispositions or masks wrt these signals.1486// Programs embedding the VM that want to use the above signals for their1487// own purposes must, at this time, use the "-Xrs" option to prevent1488// interference with shutdown hooks and BREAK_SIGNAL thread dumping.1489// (See bug 4345157, and other related bugs).1490// In reality, though, unblocking these signals is really a nop, since1491// these signals are not blocked by default.1492sigemptyset(&unblocked_sigs);1493sigaddset(&unblocked_sigs, SIGILL);1494sigaddset(&unblocked_sigs, SIGSEGV);1495sigaddset(&unblocked_sigs, SIGBUS);1496sigaddset(&unblocked_sigs, SIGFPE);1497PPC64_ONLY(sigaddset(&unblocked_sigs, SIGTRAP);)1498sigaddset(&unblocked_sigs, PosixSignals::SR_signum);14991500if (!ReduceSignalUsage) {1501if (!PosixSignals::is_sig_ignored(SHUTDOWN1_SIGNAL)) {1502sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);1503}1504if (!PosixSignals::is_sig_ignored(SHUTDOWN2_SIGNAL)) {1505sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);1506}1507if (!PosixSignals::is_sig_ignored(SHUTDOWN3_SIGNAL)) {1508sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);1509}1510}1511// Fill in signals that are blocked by all but the VM thread.1512sigemptyset(&vm_sigs);1513if (!ReduceSignalUsage) {1514sigaddset(&vm_sigs, BREAK_SIGNAL);1515}1516debug_only(signal_sets_initialized = true);1517}15181519// These are signals that are unblocked while a thread is running Java.1520// (For some reason, they get blocked by default.)1521static sigset_t* unblocked_signals() {1522assert(signal_sets_initialized, "Not initialized");1523return &unblocked_sigs;1524}15251526// These are the signals that are blocked while a (non-VM) thread is1527// running Java. Only the VM thread handles these signals.1528static sigset_t* vm_signals() {1529assert(signal_sets_initialized, "Not initialized");1530return &vm_sigs;1531}15321533void PosixSignals::hotspot_sigmask(Thread* thread) {15341535//Save caller's signal mask before setting VM signal mask1536sigset_t caller_sigmask;1537pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask);15381539OSThread* osthread = thread->osthread();1540osthread->set_caller_sigmask(caller_sigmask);15411542pthread_sigmask(SIG_UNBLOCK, unblocked_signals(), NULL);15431544if (!ReduceSignalUsage) {1545if (thread->is_VM_thread()) {1546// Only the VM thread handles BREAK_SIGNAL ...1547pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL);1548} else {1549// ... all other threads block BREAK_SIGNAL1550pthread_sigmask(SIG_BLOCK, vm_signals(), NULL);1551}1552}1553}15541555////////////////////////////////////////////////////////////////////////////////1556// suspend/resume support15571558// The low-level signal-based suspend/resume support is a remnant from the1559// old VM-suspension that used to be for java-suspension, safepoints etc,1560// within hotspot. Currently used by JFR's OSThreadSampler1561//1562// The remaining code is greatly simplified from the more general suspension1563// code that used to be used.1564//1565// The protocol is quite simple:1566// - suspend:1567// - sends a signal to the target thread1568// - polls the suspend state of the osthread using a yield loop1569// - target thread signal handler (SR_handler) sets suspend state1570// and blocks in sigsuspend until continued1571// - resume:1572// - sets target osthread state to continue1573// - sends signal to end the sigsuspend loop in the SR_handler1574//1575// Note that resume_clear_context() and suspend_save_context() are needed1576// by SR_handler(), so that fetch_frame_from_context() works,1577// which in part is used by:1578// - Forte Analyzer: AsyncGetCallTrace()1579// - StackBanging: get_frame_at_stack_banging_point()15801581sigset_t SR_sigset;15821583static void resume_clear_context(OSThread *osthread) {1584osthread->set_ucontext(NULL);1585osthread->set_siginfo(NULL);1586}15871588static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {1589osthread->set_ucontext(context);1590osthread->set_siginfo(siginfo);1591}15921593// Handler function invoked when a thread's execution is suspended or1594// resumed. We have to be careful that only async-safe functions are1595// called here (Note: most pthread functions are not async safe and1596// should be avoided.)1597//1598// Note: sigwait() is a more natural fit than sigsuspend() from an1599// interface point of view, but sigwait() prevents the signal handler1600// from being run. libpthread would get very confused by not having1601// its signal handlers run and prevents sigwait()'s use with the1602// mutex granting signal.1603//1604// Currently only ever called on the VMThread and JavaThreads (PC sampling)1605//1606static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {16071608// Save and restore errno to avoid confusing native code with EINTR1609// after sigsuspend.1610int old_errno = errno;16111612PosixSignals::unblock_error_signals();16131614Thread* thread = Thread::current_or_null_safe();1615assert(thread != NULL, "Missing current thread in SR_handler");16161617// On some systems we have seen signal delivery get "stuck" until the signal1618// mask is changed as part of thread termination. Check that the current thread1619// has not already terminated - else the following assertion1620// will fail because the thread is no longer a JavaThread as the ~JavaThread1621// destructor has completed.16221623if (thread->has_terminated()) {1624return;1625}16261627assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");16281629OSThread* osthread = thread->osthread();16301631os::SuspendResume::State current = osthread->sr.state();16321633if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {1634suspend_save_context(osthread, siginfo, context);16351636// attempt to switch the state, we assume we had a SUSPEND_REQUEST1637os::SuspendResume::State state = osthread->sr.suspended();1638if (state == os::SuspendResume::SR_SUSPENDED) {1639sigset_t suspend_set; // signals for sigsuspend()1640sigemptyset(&suspend_set);16411642// get current set of blocked signals and unblock resume signal1643pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);1644sigdelset(&suspend_set, PosixSignals::SR_signum);16451646sr_semaphore.signal();16471648// wait here until we are resumed1649while (1) {1650sigsuspend(&suspend_set);16511652os::SuspendResume::State result = osthread->sr.running();1653if (result == os::SuspendResume::SR_RUNNING) {1654// double check AIX doesn't need this!1655sr_semaphore.signal();1656break;1657} else if (result != os::SuspendResume::SR_SUSPENDED) {1658ShouldNotReachHere();1659}1660}16611662} else if (state == os::SuspendResume::SR_RUNNING) {1663// request was cancelled, continue1664} else {1665ShouldNotReachHere();1666}16671668resume_clear_context(osthread);1669} else if (current == os::SuspendResume::SR_RUNNING) {1670// request was cancelled, continue1671} else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {1672// ignore1673} else {1674// ignore1675}16761677errno = old_errno;1678}16791680int SR_initialize() {1681struct sigaction act;1682char *s;1683// Get signal number to use for suspend/resume1684if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {1685int sig = ::strtol(s, 0, 10);1686if (sig > MAX2(SIGSEGV, SIGBUS) && // See 4355769.1687sig < NSIG) { // Must be legal signal and fit into sigflags[].1688PosixSignals::SR_signum = sig;1689} else {1690warning("You set _JAVA_SR_SIGNUM=%d. It must be in range [%d, %d]. Using %d instead.",1691sig, MAX2(SIGSEGV, SIGBUS)+1, NSIG-1, PosixSignals::SR_signum);1692}1693}16941695assert(PosixSignals::SR_signum > SIGSEGV && PosixSignals::SR_signum > SIGBUS,1696"SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");16971698sigemptyset(&SR_sigset);1699sigaddset(&SR_sigset, PosixSignals::SR_signum);17001701// Set up signal handler for suspend/resume1702act.sa_flags = SA_RESTART|SA_SIGINFO;1703act.sa_handler = (void (*)(int)) SR_handler;17041705// SR_signum is blocked by default.1706pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask);1707remove_error_signals_from_set(&(act.sa_mask));17081709if (sigaction(PosixSignals::SR_signum, &act, 0) == -1) {1710return -1;1711}17121713// Save signal setup information for later checking.1714vm_handlers.set(PosixSignals::SR_signum, &act);1715do_check_signal_periodically[PosixSignals::SR_signum] = true;17161717return 0;1718}17191720static int sr_notify(OSThread* osthread) {1721int status = pthread_kill(osthread->pthread_id(), PosixSignals::SR_signum);1722assert_status(status == 0, status, "pthread_kill");1723return status;1724}17251726// returns true on success and false on error - really an error is fatal1727// but this seems the normal response to library errors1728bool PosixSignals::do_suspend(OSThread* osthread) {1729assert(osthread->sr.is_running(), "thread should be running");1730assert(!sr_semaphore.trywait(), "semaphore has invalid state");17311732// mark as suspended and send signal1733if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {1734// failed to switch, state wasn't running?1735ShouldNotReachHere();1736return false;1737}17381739if (sr_notify(osthread) != 0) {1740ShouldNotReachHere();1741}17421743// managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED1744while (true) {1745if (sr_semaphore.timedwait(2)) {1746break;1747} else {1748// timeout1749os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();1750if (cancelled == os::SuspendResume::SR_RUNNING) {1751return false;1752} else if (cancelled == os::SuspendResume::SR_SUSPENDED) {1753// make sure that we consume the signal on the semaphore as well1754sr_semaphore.wait();1755break;1756} else {1757ShouldNotReachHere();1758return false;1759}1760}1761}17621763guarantee(osthread->sr.is_suspended(), "Must be suspended");1764return true;1765}17661767void PosixSignals::do_resume(OSThread* osthread) {1768assert(osthread->sr.is_suspended(), "thread should be suspended");1769assert(!sr_semaphore.trywait(), "invalid semaphore state");17701771if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {1772// failed to switch to WAKEUP_REQUEST1773ShouldNotReachHere();1774return;1775}17761777while (true) {1778if (sr_notify(osthread) == 0) {1779if (sr_semaphore.timedwait(2)) {1780if (osthread->sr.is_running()) {1781return;1782}1783}1784} else {1785ShouldNotReachHere();1786}1787}17881789guarantee(osthread->sr.is_running(), "Must be running!");1790}17911792void os::SuspendedThreadTask::internal_do_task() {1793if (PosixSignals::do_suspend(_thread->osthread())) {1794os::SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());1795do_task(context);1796PosixSignals::do_resume(_thread->osthread());1797}1798}17991800int PosixSignals::init() {1801// initialize suspend/resume support - must do this before signal_sets_init()1802if (SR_initialize() != 0) {1803vm_exit_during_initialization("SR_initialize failed");1804return JNI_ERR;1805}18061807signal_sets_init();18081809install_signal_handlers();18101811// Initialize data for jdk.internal.misc.Signal1812if (!ReduceSignalUsage) {1813jdk_misc_signal_init();1814}18151816return JNI_OK;1817}181818191820