Path: blob/master/src/hotspot/os/posix/signals_posix.cpp
40930 views
/*1* Copyright (c) 2021, 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#ifdef ZERO43// See stubGenerator_zero.cpp44#include <setjmp.h>45extern sigjmp_buf* get_jmp_buf_for_continuation();46#endif4748#include <signal.h>495051static const char* get_signal_name(int sig, char* out, size_t outlen);5253// Returns address of a handler associated with the given sigaction54static address get_signal_handler(const struct sigaction* action);5556#define HANDLER_IS(handler, address) ((handler) == CAST_FROM_FN_PTR(void*, (address)))57#define HANDLER_IS_IGN(handler) (HANDLER_IS(handler, SIG_IGN))58#define HANDLER_IS_DFL(handler) (HANDLER_IS(handler, SIG_DFL))59#define HANDLER_IS_IGN_OR_DFL(handler) (HANDLER_IS_IGN(handler) || HANDLER_IS_DFL(handler))6061// Various signal related mechanism are laid out in the following order:62//63// sun.misc.Signal64// signal chaining65// signal handling (except suspend/resume)66// suspend/resume6768// Helper function to strip any flags from a sigaction sa_flag69// which are not needed for semantic comparison (see remarks below70// about SA_RESTORER on Linux).71// Also to work around the fact that not all platforms define sa_flags72// as signed int (looking at you, zlinux).73static int get_sanitized_sa_flags(const struct sigaction* sa) {74int f = (int) sa->sa_flags;75#ifdef LINUX76// Glibc on Linux uses the SA_RESTORER flag to indicate77// the use of a "signal trampoline". We have no interest78// in this flag and need to ignore it when checking our79// own flag settings.80// Note: SA_RESTORER is not exposed through signal.h so we81// have to hardcode its 0x04000000 value here.82const int sa_restorer_flag = 0x04000000;83f &= ~sa_restorer_flag;84#endif // LINUX85return f;86}8788// Todo: provide a os::get_max_process_id() or similar. Number of processes89// may have been configured, can be read more accurately from proc fs etc.90#ifndef MAX_PID91#define MAX_PID INT_MAX92#endif93#define IS_VALID_PID(p) (p > 0 && p < MAX_PID)9495#define NUM_IMPORTANT_SIGS 329697extern "C" {98typedef void (*sa_handler_t)(int);99typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);100}101102// At various places we store handler information for each installed handler.103// SavedSignalHandlers is a helper class for those cases, keeping an array of sigaction104// structures.105class SavedSignalHandlers {106// Note: NSIG can be largish, depending on platform, and this array is expected107// to be sparsely populated. To save space the contained structures are108// C-heap allocated. Since they only get added outside of signal handling109// this is no problem.110struct sigaction* _sa[NSIG];111112bool check_signal_number(int sig) const {113assert(sig > 0 && sig < NSIG, "invalid signal number %d", sig);114return sig > 0 && sig < NSIG;115}116117public:118119SavedSignalHandlers() {120::memset(_sa, 0, sizeof(_sa));121}122123~SavedSignalHandlers() {124for (int i = 0; i < NSIG; i ++) {125FREE_C_HEAP_OBJ(_sa[i]);126}127}128129void set(int sig, const struct sigaction* act) {130if (check_signal_number(sig)) {131assert(_sa[sig] == NULL, "Overwriting signal handler?");132_sa[sig] = NEW_C_HEAP_OBJ(struct sigaction, mtInternal);133*_sa[sig] = *act;134}135}136137const struct sigaction* get(int sig) const {138if (check_signal_number(sig)) {139return _sa[sig];140}141return NULL;142}143};144145146debug_only(static bool signal_sets_initialized = false);147static sigset_t unblocked_sigs, vm_sigs, preinstalled_sigs;148149// Our own signal handlers should never ever get replaced by a third party one.150// To check that, and to aid with diagnostics, store a copy of the handler setup151// and compare it periodically against reality (see os::run_periodic_checks()).152static bool check_signals = true;153static SavedSignalHandlers vm_handlers;154static bool do_check_signal_periodically[NSIG] = { 0 };155156// For signal-chaining:157// if chaining is active, chained_handlers contains all handlers which we158// replaced with our own and to which we must delegate.159static SavedSignalHandlers chained_handlers;160static bool libjsig_is_loaded = false;161typedef struct sigaction *(*get_signal_t)(int);162static get_signal_t get_signal_action = NULL;163164// suspend/resume support165#if defined(__APPLE__)166static OSXSemaphore sr_semaphore;167#else168static PosixSemaphore sr_semaphore;169#endif170171// Signal number used to suspend/resume a thread172// do not use any signal number less than SIGSEGV, see 4355769173int PosixSignals::SR_signum = SIGUSR2;174175// sun.misc.Signal support176static Semaphore* sig_semaphore = NULL;177// a counter for each possible signal value178static volatile jint pending_signals[NSIG+1] = { 0 };179180static const struct {181int sig; const char* name;182} g_signal_info[] = {183{ SIGABRT, "SIGABRT" },184#ifdef SIGAIO185{ SIGAIO, "SIGAIO" },186#endif187{ SIGALRM, "SIGALRM" },188#ifdef SIGALRM1189{ SIGALRM1, "SIGALRM1" },190#endif191{ SIGBUS, "SIGBUS" },192#ifdef SIGCANCEL193{ SIGCANCEL, "SIGCANCEL" },194#endif195{ SIGCHLD, "SIGCHLD" },196#ifdef SIGCLD197{ SIGCLD, "SIGCLD" },198#endif199{ SIGCONT, "SIGCONT" },200#ifdef SIGCPUFAIL201{ SIGCPUFAIL, "SIGCPUFAIL" },202#endif203#ifdef SIGDANGER204{ SIGDANGER, "SIGDANGER" },205#endif206#ifdef SIGDIL207{ SIGDIL, "SIGDIL" },208#endif209#ifdef SIGEMT210{ SIGEMT, "SIGEMT" },211#endif212{ SIGFPE, "SIGFPE" },213#ifdef SIGFREEZE214{ SIGFREEZE, "SIGFREEZE" },215#endif216#ifdef SIGGFAULT217{ SIGGFAULT, "SIGGFAULT" },218#endif219#ifdef SIGGRANT220{ SIGGRANT, "SIGGRANT" },221#endif222{ SIGHUP, "SIGHUP" },223{ SIGILL, "SIGILL" },224#ifdef SIGINFO225{ SIGINFO, "SIGINFO" },226#endif227{ SIGINT, "SIGINT" },228#ifdef SIGIO229{ SIGIO, "SIGIO" },230#endif231#ifdef SIGIOINT232{ SIGIOINT, "SIGIOINT" },233#endif234#ifdef SIGIOT235// SIGIOT is there for BSD compatibility, but on most Unices just a236// synonym for SIGABRT. The result should be "SIGABRT", not237// "SIGIOT".238#if (SIGIOT != SIGABRT )239{ SIGIOT, "SIGIOT" },240#endif241#endif242#ifdef SIGKAP243{ SIGKAP, "SIGKAP" },244#endif245{ SIGKILL, "SIGKILL" },246#ifdef SIGLOST247{ SIGLOST, "SIGLOST" },248#endif249#ifdef SIGLWP250{ SIGLWP, "SIGLWP" },251#endif252#ifdef SIGLWPTIMER253{ SIGLWPTIMER, "SIGLWPTIMER" },254#endif255#ifdef SIGMIGRATE256{ SIGMIGRATE, "SIGMIGRATE" },257#endif258#ifdef SIGMSG259{ SIGMSG, "SIGMSG" },260#endif261{ SIGPIPE, "SIGPIPE" },262#ifdef SIGPOLL263{ SIGPOLL, "SIGPOLL" },264#endif265#ifdef SIGPRE266{ SIGPRE, "SIGPRE" },267#endif268{ SIGPROF, "SIGPROF" },269#ifdef SIGPTY270{ SIGPTY, "SIGPTY" },271#endif272#ifdef SIGPWR273{ SIGPWR, "SIGPWR" },274#endif275{ SIGQUIT, "SIGQUIT" },276#ifdef SIGRECONFIG277{ SIGRECONFIG, "SIGRECONFIG" },278#endif279#ifdef SIGRECOVERY280{ SIGRECOVERY, "SIGRECOVERY" },281#endif282#ifdef SIGRESERVE283{ SIGRESERVE, "SIGRESERVE" },284#endif285#ifdef SIGRETRACT286{ SIGRETRACT, "SIGRETRACT" },287#endif288#ifdef SIGSAK289{ SIGSAK, "SIGSAK" },290#endif291{ SIGSEGV, "SIGSEGV" },292#ifdef SIGSOUND293{ SIGSOUND, "SIGSOUND" },294#endif295#ifdef SIGSTKFLT296{ SIGSTKFLT, "SIGSTKFLT" },297#endif298{ SIGSTOP, "SIGSTOP" },299{ SIGSYS, "SIGSYS" },300#ifdef SIGSYSERROR301{ SIGSYSERROR, "SIGSYSERROR" },302#endif303#ifdef SIGTALRM304{ SIGTALRM, "SIGTALRM" },305#endif306{ SIGTERM, "SIGTERM" },307#ifdef SIGTHAW308{ SIGTHAW, "SIGTHAW" },309#endif310{ SIGTRAP, "SIGTRAP" },311#ifdef SIGTSTP312{ SIGTSTP, "SIGTSTP" },313#endif314{ SIGTTIN, "SIGTTIN" },315{ SIGTTOU, "SIGTTOU" },316#ifdef SIGURG317{ SIGURG, "SIGURG" },318#endif319{ SIGUSR1, "SIGUSR1" },320{ SIGUSR2, "SIGUSR2" },321#ifdef SIGVIRT322{ SIGVIRT, "SIGVIRT" },323#endif324{ SIGVTALRM, "SIGVTALRM" },325#ifdef SIGWAITING326{ SIGWAITING, "SIGWAITING" },327#endif328#ifdef SIGWINCH329{ SIGWINCH, "SIGWINCH" },330#endif331#ifdef SIGWINDOW332{ SIGWINDOW, "SIGWINDOW" },333#endif334{ SIGXCPU, "SIGXCPU" },335{ SIGXFSZ, "SIGXFSZ" },336#ifdef SIGXRES337{ SIGXRES, "SIGXRES" },338#endif339{ -1, NULL }340};341342////////////////////////////////////////////////////////////////////////////////343// sun.misc.Signal support344345void jdk_misc_signal_init() {346// Initialize signal structures347::memset((void*)pending_signals, 0, sizeof(pending_signals));348349// Initialize signal semaphore350sig_semaphore = new Semaphore();351}352353void os::signal_notify(int sig) {354if (sig_semaphore != NULL) {355Atomic::inc(&pending_signals[sig]);356sig_semaphore->signal();357} else {358// Signal thread is not created with ReduceSignalUsage and jdk_misc_signal_init359// initialization isn't called.360assert(ReduceSignalUsage, "signal semaphore should be created");361}362}363364static int check_pending_signals() {365for (;;) {366for (int i = 0; i < NSIG + 1; i++) {367jint n = pending_signals[i];368if (n > 0 && n == Atomic::cmpxchg(&pending_signals[i], n, n - 1)) {369return i;370}371}372sig_semaphore->wait_with_safepoint_check(JavaThread::current());373}374ShouldNotReachHere();375return 0; // Satisfy compiler376}377378int os::signal_wait() {379return check_pending_signals();380}381382////////////////////////////////////////////////////////////////////////////////383// signal chaining support384385struct sigaction* get_chained_signal_action(int sig) {386struct sigaction *actp = NULL;387388if (libjsig_is_loaded) {389// Retrieve the old signal handler from libjsig390actp = (*get_signal_action)(sig);391}392if (actp == NULL) {393// Retrieve the preinstalled signal handler from jvm394actp = const_cast<struct sigaction*>(chained_handlers.get(sig));395}396397return actp;398}399400static bool call_chained_handler(struct sigaction *actp, int sig,401siginfo_t *siginfo, void *context) {402// Call the old signal handler403if (actp->sa_handler == SIG_DFL) {404// It's more reasonable to let jvm treat it as an unexpected exception405// instead of taking the default action.406return false;407} else if (actp->sa_handler != SIG_IGN) {408if ((actp->sa_flags & SA_NODEFER) == 0) {409// automaticlly block the signal410sigaddset(&(actp->sa_mask), sig);411}412413sa_handler_t hand = NULL;414sa_sigaction_t sa = NULL;415bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;416// retrieve the chained handler417if (siginfo_flag_set) {418sa = actp->sa_sigaction;419} else {420hand = actp->sa_handler;421}422423if ((actp->sa_flags & SA_RESETHAND) != 0) {424actp->sa_handler = SIG_DFL;425}426427// try to honor the signal mask428sigset_t oset;429sigemptyset(&oset);430pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);431432// call into the chained handler433if (siginfo_flag_set) {434(*sa)(sig, siginfo, context);435} else {436(*hand)(sig);437}438439// restore the signal mask440pthread_sigmask(SIG_SETMASK, &oset, NULL);441}442// Tell jvm's signal handler the signal is taken care of.443return true;444}445446bool PosixSignals::chained_handler(int sig, siginfo_t* siginfo, void* context) {447bool chained = false;448// signal-chaining449if (UseSignalChaining) {450struct sigaction *actp = get_chained_signal_action(sig);451if (actp != NULL) {452chained = call_chained_handler(actp, sig, siginfo, context);453}454}455return chained;456}457458///// Synchronous (non-deferrable) error signals (ILL, SEGV, FPE, BUS, TRAP):459460// These signals are special because they cannot be deferred and, if they461// happen while delivery is blocked for the receiving thread, will cause UB462// (in practice typically resulting in sudden process deaths or hangs, see463// JDK-8252533). So we must take care never to block them when we cannot be464// absolutely sure they won't happen. In practice, this is always.465//466// Relevant Posix quote:467// "The behavior of a process is undefined after it ignores a SIGFPE, SIGILL,468// SIGSEGV, or SIGBUS signal that was not generated by kill(), sigqueue(), or469// raise()."470//471// We also include SIGTRAP in that list of never-to-block-signals. While not472// mentioned by the Posix documentation, in our (SAPs) experience blocking it473// causes similar problems. Beside, during normal operation - outside of error474// handling - SIGTRAP may be used for implicit NULL checking, so it makes sense475// to never block it.476//477// We deal with those signals in two ways:478// - we just never explicitly block them, which includes not accidentally blocking479// them via sa_mask when establishing signal handlers.480// - as an additional safety measure, at the entrance of a signal handler, we481// unblock them explicitly.482483static void add_error_signals_to_set(sigset_t* set) {484sigaddset(set, SIGILL);485sigaddset(set, SIGBUS);486sigaddset(set, SIGFPE);487sigaddset(set, SIGSEGV);488sigaddset(set, SIGTRAP);489}490491static void remove_error_signals_from_set(sigset_t* set) {492sigdelset(set, SIGILL);493sigdelset(set, SIGBUS);494sigdelset(set, SIGFPE);495sigdelset(set, SIGSEGV);496sigdelset(set, SIGTRAP);497}498499// Unblock all signals whose delivery cannot be deferred and which, if they happen500// while delivery is blocked, would cause crashes or hangs (JDK-8252533).501void PosixSignals::unblock_error_signals() {502sigset_t set;503sigemptyset(&set);504add_error_signals_to_set(&set);505::pthread_sigmask(SIG_UNBLOCK, &set, NULL);506}507508class ErrnoPreserver: public StackObj {509const int _saved;510public:511ErrnoPreserver() : _saved(errno) {}512~ErrnoPreserver() { errno = _saved; }513};514515////////////////////////////////////////////////////////////////////////////////516// JVM_handle_(linux|aix|bsd)_signal()517518// This routine is the shared part of the central hotspot signal handler. It can519// also be called by a user application, if a user application prefers to do520// signal handling itself - in that case it needs to pass signals the VM521// internally uses on to the VM first.522//523// The user-defined signal handler must pass unrecognized signals to this524// routine, and if it returns true (non-zero), then the signal handler must525// return immediately. If the flag "abort_if_unrecognized" is true, then this526// routine will never return false (zero), but instead will execute a VM panic527// routine to kill the process.528//529// If this routine returns false, it is OK to call it again. This allows530// the user-defined signal handler to perform checks either before or after531// the VM performs its own checks. Naturally, the user code would be making532// a serious error if it tried to handle an exception (such as a null check533// or breakpoint) that the VM was generating for its own correct operation.534//535// This routine may recognize any of the following kinds of signals:536// SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1.537// It should be consulted by handlers for any of those signals.538//539// The caller of this routine must pass in the three arguments supplied540// to the function referred to in the "sa_sigaction" (not the "sa_handler")541// field of the structure passed to sigaction(). This routine assumes that542// the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.543//544// Note that the VM will print warnings if it detects conflicting signal545// handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".546//547548#if defined(BSD)549#define JVM_HANDLE_XXX_SIGNAL JVM_handle_bsd_signal550#elif defined(AIX)551#define JVM_HANDLE_XXX_SIGNAL JVM_handle_aix_signal552#elif defined(LINUX)553#define JVM_HANDLE_XXX_SIGNAL JVM_handle_linux_signal554#else555#error who are you?556#endif557558extern "C" JNIEXPORT559int JVM_HANDLE_XXX_SIGNAL(int sig, siginfo_t* info,560void* ucVoid, int abort_if_unrecognized)561{562assert(info != NULL && ucVoid != NULL, "sanity");563564// Note: it's not uncommon that JNI code uses signal/sigset to install,565// then restore certain signal handler (e.g. to temporarily block SIGPIPE,566// or have a SIGILL handler when detecting CPU type). When that happens,567// this handler might be invoked with junk info/ucVoid. To avoid unnecessary568// crash when libjsig is not preloaded, try handle signals that do not require569// siginfo/ucontext first.570571// Preserve errno value over signal handler.572// (note: RAII ok here, even with JFR thread crash protection, see below).573ErrnoPreserver ep;574575// Unblock all synchronous error signals (see JDK-8252533)576PosixSignals::unblock_error_signals();577578ucontext_t* const uc = (ucontext_t*) ucVoid;579Thread* const t = Thread::current_or_null_safe();580581// Handle JFR thread crash protection.582// Note: this may cause us to longjmp away. Do not use any code before this583// point which really needs any form of epilogue code running, eg RAII objects.584os::ThreadCrashProtection::check_crash_protection(sig, t);585586bool signal_was_handled = false;587588// Handle assertion poison page accesses.589#ifdef CAN_SHOW_REGISTERS_ON_ASSERT590if (!signal_was_handled &&591((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison)) {592signal_was_handled = handle_assert_poison_fault(ucVoid, info->si_addr);593}594#endif595596if (!signal_was_handled) {597// Handle SafeFetch access.598#ifndef ZERO599if (uc != NULL) {600address pc = os::Posix::ucontext_get_pc(uc);601if (StubRoutines::is_safefetch_fault(pc)) {602os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));603signal_was_handled = true;604}605}606#else607// See JDK-8076185608if (sig == SIGSEGV || sig == SIGBUS) {609sigjmp_buf* const pjb = get_jmp_buf_for_continuation();610if (pjb) {611siglongjmp(*pjb, 1);612}613}614#endif // ZERO615}616617// Ignore SIGPIPE and SIGXFSZ (4229104, 6499219).618if (!signal_was_handled &&619(sig == SIGPIPE || sig == SIGXFSZ)) {620PosixSignals::chained_handler(sig, info, ucVoid);621signal_was_handled = true; // unconditionally.622}623624// Call platform dependent signal handler.625if (!signal_was_handled) {626JavaThread* const jt = (t != NULL && t->is_Java_thread()) ? (JavaThread*) t : NULL;627signal_was_handled = PosixSignals::pd_hotspot_signal_handler(sig, info, uc, jt);628}629630// From here on, if the signal had not been handled, it is a fatal error.631632// Give the chained signal handler - should it exist - a shot.633if (!signal_was_handled) {634signal_was_handled = PosixSignals::chained_handler(sig, info, ucVoid);635}636637// Invoke fatal error handling.638if (!signal_was_handled && abort_if_unrecognized) {639// Extract pc from context for the error handler to display.640address pc = NULL;641if (uc != NULL) {642// prepare fault pc address for error reporting.643if (S390_ONLY(sig == SIGILL || sig == SIGFPE) NOT_S390(false)) {644pc = (address)info->si_addr;645} else if (ZERO_ONLY(true) NOT_ZERO(false)) {646// Non-arch-specific Zero code does not really know the pc.647// This can be alleviated by making arch-specific os::Posix::ucontext_get_pc648// available for Zero for known architectures. But for generic Zero649// code, it would still remain unknown.650pc = NULL;651} else {652pc = os::Posix::ucontext_get_pc(uc);653}654}655// For Zero, we ignore the crash context, because:656// a) The crash would be in C++ interpreter code, so context is not really relevant;657// b) Generic Zero code would not be able to parse it, so when generic error658// reporting code asks e.g. about frames on stack, Zero would experience659// a secondary ShouldNotCallThis() crash.660VMError::report_and_die(t, sig, pc, info, NOT_ZERO(ucVoid) ZERO_ONLY(NULL));661// VMError should not return.662ShouldNotReachHere();663}664return signal_was_handled;665}666667// Entry point for the hotspot signal handler.668static void javaSignalHandler(int sig, siginfo_t* info, void* ucVoid) {669// Do not add any code here!670// Only add code to either JVM_HANDLE_XXX_SIGNAL or PosixSignals::pd_hotspot_signal_handler.671(void)JVM_HANDLE_XXX_SIGNAL(sig, info, ucVoid, true);672}673674static void UserHandler(int sig, void *siginfo, void *context) {675676PosixSignals::unblock_error_signals();677678// Ctrl-C is pressed during error reporting, likely because the error679// handler fails to abort. Let VM die immediately.680if (sig == SIGINT && VMError::is_error_reported()) {681os::die();682}683684os::signal_notify(sig);685}686687static void print_signal_handler_name(outputStream* os, address handler, char* buf, size_t buflen) {688// We demangle, but omit arguments - signal handlers should have always the same prototype.689os::print_function_and_library_name(os, handler, buf, buflen,690true, // shorten_path691true, // demangle692true // omit arguments693);694}695696// Writes one-line description of a combination of sigaction.sa_flags into a user697// provided buffer. Returns that buffer.698static const char* describe_sa_flags(int flags, char* buffer, size_t size) {699char* p = buffer;700size_t remaining = size;701bool first = true;702int idx = 0;703704assert(buffer, "invalid argument");705706if (size == 0) {707return buffer;708}709710strncpy(buffer, "none", size);711712const unsigned int unknown_flag = ~(SA_NOCLDSTOP |713SA_ONSTACK |714SA_NOCLDSTOP |715SA_RESTART |716SA_SIGINFO |717SA_NOCLDWAIT |718SA_NODEFER719AIX_ONLY(| SA_OLDSTYLE)720);721722const struct {723// NB: i is an unsigned int here because SA_RESETHAND is on some724// systems 0x80000000, which is implicitly unsigned. Assigning725// it to an int field would be an overflow in unsigned-to-signed726// conversion.727unsigned int i;728const char* s;729} flaginfo [] = {730{ SA_NOCLDSTOP, "SA_NOCLDSTOP" },731{ SA_ONSTACK, "SA_ONSTACK" },732{ SA_RESETHAND, "SA_RESETHAND" },733{ SA_RESTART, "SA_RESTART" },734{ SA_SIGINFO, "SA_SIGINFO" },735{ SA_NOCLDWAIT, "SA_NOCLDWAIT" },736{ SA_NODEFER, "SA_NODEFER" },737#if defined(AIX)738{ SA_OLDSTYLE, "SA_OLDSTYLE" },739#endif740{ unknown_flag, "NOT USED" }741};742743for (idx = 0; flaginfo[idx].i != unknown_flag && remaining > 1; idx++) {744if (flags & flaginfo[idx].i) {745if (first) {746jio_snprintf(p, remaining, "%s", flaginfo[idx].s);747first = false;748} else {749jio_snprintf(p, remaining, "|%s", flaginfo[idx].s);750}751const size_t len = strlen(p);752p += len;753remaining -= len;754}755}756unsigned int unknowns = flags & unknown_flag;757if (unknowns != 0) {758jio_snprintf(p, remaining, "|Unknown_flags:%x", unknowns);759}760761buffer[size - 1] = '\0';762763return buffer;764}765766// Prints one-line description of a combination of sigaction.sa_flags.767static void print_sa_flags(outputStream* st, int flags) {768char buffer[0x100];769describe_sa_flags(flags, buffer, sizeof(buffer));770st->print("%s", buffer);771}772773// Implementation may use the same storage for both the sa_sigaction field and the sa_handler field,774// so check for "sigAct.sa_flags == SA_SIGINFO"775static address get_signal_handler(const struct sigaction* action) {776bool siginfo_flag_set = (action->sa_flags & SA_SIGINFO) != 0;777if (siginfo_flag_set) {778return CAST_FROM_FN_PTR(address, action->sa_sigaction);779} else {780return CAST_FROM_FN_PTR(address, action->sa_handler);781}782}783784typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);785786static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context);787788// Semantically compare two sigaction structures. Return true if they are referring to789// the same handler, using the same flags.790static bool are_handlers_equal(const struct sigaction* sa,791const struct sigaction* expected_sa) {792address this_handler = get_signal_handler(sa);793address expected_handler = get_signal_handler(expected_sa);794const int this_flags = get_sanitized_sa_flags(sa);795const int expected_flags = get_sanitized_sa_flags(expected_sa);796return (this_handler == expected_handler) &&797(this_flags == expected_flags);798}799800// If we installed one of our signal handlers for sig, check that the current801// setup matches what we originally installed.802static void check_signal_handler(int sig) {803char buf[O_BUFLEN];804bool mismatch = false;805806if (!do_check_signal_periodically[sig]) {807return;808}809810const struct sigaction* expected_act = vm_handlers.get(sig);811assert(expected_act != NULL, "Sanity");812813// Retrieve current signal setup.814struct sigaction act;815static os_sigaction_t os_sigaction = NULL;816if (os_sigaction == NULL) {817// only trust the default sigaction, in case it has been interposed818os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");819if (os_sigaction == NULL) return;820}821822os_sigaction(sig, (struct sigaction*)NULL, &act);823824// Compare both sigaction structures (intelligently; only the members we care about).825if (!are_handlers_equal(&act, expected_act)) {826tty->print_cr("Warning: %s handler modified!", os::exception_name(sig, buf, sizeof(buf)));827// If we had a mismatch:828// - print all signal handlers. As part of that printout, details will be printed829// about any modified handlers.830// - Disable any further checks for this signal - we do not want to flood stdout. Though831// depending on which signal had been overwritten, we may die very soon anyway.832os::print_signal_handlers(tty, buf, O_BUFLEN);833do_check_signal_periodically[sig] = false;834tty->print_cr("Consider using jsig library.");835// Running under non-interactive shell, SHUTDOWN2_SIGNAL will be reassigned SIG_IGN836if (sig == SHUTDOWN2_SIGNAL && !isatty(fileno(stdin))) {837tty->print_cr("Note: Running in non-interactive shell, %s handler is replaced by shell",838os::exception_name(sig, buf, O_BUFLEN));839}840}841}842843void* os::user_handler() {844return CAST_FROM_FN_PTR(void*, UserHandler);845}846847void* os::signal(int signal_number, void* handler) {848struct sigaction sigAct, oldSigAct;849850sigfillset(&(sigAct.sa_mask));851remove_error_signals_from_set(&(sigAct.sa_mask));852853sigAct.sa_flags = SA_RESTART|SA_SIGINFO;854sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);855856if (sigaction(signal_number, &sigAct, &oldSigAct)) {857// -1 means registration failed858return (void *)-1;859}860861return get_signal_handler(&oldSigAct);862}863864void os::signal_raise(int signal_number) {865::raise(signal_number);866}867868// Will be modified when max signal is changed to be dynamic869int os::sigexitnum_pd() {870return NSIG;871}872873// This method is a periodic task to check for misbehaving JNI applications874// under CheckJNI, we can add any periodic checks here875void os::run_periodic_checks() {876877if (check_signals == false) return;878879// SEGV and BUS if overridden could potentially prevent880// generation of hs*.log in the event of a crash, debugging881// such a case can be very challenging, so we absolutely882// check the following for a good measure:883check_signal_handler(SIGSEGV);884check_signal_handler(SIGILL);885check_signal_handler(SIGFPE);886check_signal_handler(SIGBUS);887check_signal_handler(SIGPIPE);888check_signal_handler(SIGXFSZ);889PPC64_ONLY(check_signal_handler(SIGTRAP);)890891// ReduceSignalUsage allows the user to override these handlers892// see comments at the very top and jvm_md.h893if (!ReduceSignalUsage) {894check_signal_handler(SHUTDOWN1_SIGNAL);895check_signal_handler(SHUTDOWN2_SIGNAL);896check_signal_handler(SHUTDOWN3_SIGNAL);897check_signal_handler(BREAK_SIGNAL);898}899900check_signal_handler(PosixSignals::SR_signum);901}902903// Helper function for PosixSignals::print_siginfo_...():904// return a textual description for signal code.905struct enum_sigcode_desc_t {906const char* s_name;907const char* s_desc;908};909910static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t* out) {911912const struct {913int sig; int code; const char* s_code; const char* s_desc;914} t1 [] = {915{ SIGILL, ILL_ILLOPC, "ILL_ILLOPC", "Illegal opcode." },916{ SIGILL, ILL_ILLOPN, "ILL_ILLOPN", "Illegal operand." },917{ SIGILL, ILL_ILLADR, "ILL_ILLADR", "Illegal addressing mode." },918{ SIGILL, ILL_ILLTRP, "ILL_ILLTRP", "Illegal trap." },919{ SIGILL, ILL_PRVOPC, "ILL_PRVOPC", "Privileged opcode." },920{ SIGILL, ILL_PRVREG, "ILL_PRVREG", "Privileged register." },921{ SIGILL, ILL_COPROC, "ILL_COPROC", "Coprocessor error." },922{ SIGILL, ILL_BADSTK, "ILL_BADSTK", "Internal stack error." },923#if defined(IA64) && defined(LINUX)924{ SIGILL, ILL_BADIADDR, "ILL_BADIADDR", "Unimplemented instruction address" },925{ SIGILL, ILL_BREAK, "ILL_BREAK", "Application Break instruction" },926#endif927{ SIGFPE, FPE_INTDIV, "FPE_INTDIV", "Integer divide by zero." },928{ SIGFPE, FPE_INTOVF, "FPE_INTOVF", "Integer overflow." },929{ SIGFPE, FPE_FLTDIV, "FPE_FLTDIV", "Floating-point divide by zero." },930{ SIGFPE, FPE_FLTOVF, "FPE_FLTOVF", "Floating-point overflow." },931{ SIGFPE, FPE_FLTUND, "FPE_FLTUND", "Floating-point underflow." },932{ SIGFPE, FPE_FLTRES, "FPE_FLTRES", "Floating-point inexact result." },933{ SIGFPE, FPE_FLTINV, "FPE_FLTINV", "Invalid floating-point operation." },934{ SIGFPE, FPE_FLTSUB, "FPE_FLTSUB", "Subscript out of range." },935{ SIGSEGV, SEGV_MAPERR, "SEGV_MAPERR", "Address not mapped to object." },936{ SIGSEGV, SEGV_ACCERR, "SEGV_ACCERR", "Invalid permissions for mapped object." },937#if defined(AIX)938// no explanation found what keyerr would be939{ SIGSEGV, SEGV_KEYERR, "SEGV_KEYERR", "key error" },940#endif941#if defined(IA64) && !defined(AIX)942{ SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" },943#endif944{ SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." },945{ SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." },946{ SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." },947{ SIGTRAP, TRAP_BRKPT, "TRAP_BRKPT", "Process breakpoint." },948{ SIGTRAP, TRAP_TRACE, "TRAP_TRACE", "Process trace trap." },949{ SIGCHLD, CLD_EXITED, "CLD_EXITED", "Child has exited." },950{ SIGCHLD, CLD_KILLED, "CLD_KILLED", "Child has terminated abnormally and did not create a core file." },951{ SIGCHLD, CLD_DUMPED, "CLD_DUMPED", "Child has terminated abnormally and created a core file." },952{ SIGCHLD, CLD_TRAPPED, "CLD_TRAPPED", "Traced child has trapped." },953{ SIGCHLD, CLD_STOPPED, "CLD_STOPPED", "Child has stopped." },954{ SIGCHLD, CLD_CONTINUED,"CLD_CONTINUED","Stopped child has continued." },955#ifdef SIGPOLL956{ SIGPOLL, POLL_OUT, "POLL_OUT", "Output buffers available." },957{ SIGPOLL, POLL_MSG, "POLL_MSG", "Input message available." },958{ SIGPOLL, POLL_ERR, "POLL_ERR", "I/O error." },959{ SIGPOLL, POLL_PRI, "POLL_PRI", "High priority input available." },960{ SIGPOLL, POLL_HUP, "POLL_HUP", "Device disconnected. [Option End]" },961#endif962{ -1, -1, NULL, NULL }963};964965// Codes valid in any signal context.966const struct {967int code; const char* s_code; const char* s_desc;968} t2 [] = {969{ SI_USER, "SI_USER", "Signal sent by kill()." },970{ SI_QUEUE, "SI_QUEUE", "Signal sent by the sigqueue()." },971{ SI_TIMER, "SI_TIMER", "Signal generated by expiration of a timer set by timer_settime()." },972{ SI_ASYNCIO, "SI_ASYNCIO", "Signal generated by completion of an asynchronous I/O request." },973{ SI_MESGQ, "SI_MESGQ", "Signal generated by arrival of a message on an empty message queue." },974// Linux specific975#ifdef SI_TKILL976{ SI_TKILL, "SI_TKILL", "Signal sent by tkill (pthread_kill)" },977#endif978#ifdef SI_DETHREAD979{ SI_DETHREAD, "SI_DETHREAD", "Signal sent by execve() killing subsidiary threads" },980#endif981#ifdef SI_KERNEL982{ SI_KERNEL, "SI_KERNEL", "Signal sent by kernel." },983#endif984#ifdef SI_SIGIO985{ SI_SIGIO, "SI_SIGIO", "Signal sent by queued SIGIO" },986#endif987988#if defined(AIX)989{ SI_UNDEFINED, "SI_UNDEFINED","siginfo contains partial information" },990{ SI_EMPTY, "SI_EMPTY", "siginfo contains no useful information" },991#endif992993{ -1, NULL, NULL }994};995996const char* s_code = NULL;997const char* s_desc = NULL;998999for (int i = 0; t1[i].sig != -1; i ++) {1000if (t1[i].sig == si->si_signo && t1[i].code == si->si_code) {1001s_code = t1[i].s_code;1002s_desc = t1[i].s_desc;1003break;1004}1005}10061007if (s_code == NULL) {1008for (int i = 0; t2[i].s_code != NULL; i ++) {1009if (t2[i].code == si->si_code) {1010s_code = t2[i].s_code;1011s_desc = t2[i].s_desc;1012}1013}1014}10151016if (s_code == NULL) {1017out->s_name = "unknown";1018out->s_desc = "unknown";1019return false;1020}10211022out->s_name = s_code;1023out->s_desc = s_desc;10241025return true;1026}10271028bool os::signal_sent_by_kill(const void* siginfo) {1029const siginfo_t* const si = (const siginfo_t*)siginfo;1030return si->si_code == SI_USER || si->si_code == SI_QUEUE1031#ifdef SI_TKILL1032|| si->si_code == SI_TKILL1033#endif1034;1035}10361037// Returns true if signal number is valid.1038static bool is_valid_signal(int sig) {1039// MacOS not really POSIX compliant: sigaddset does not return1040// an error for invalid signal numbers. However, MacOS does not1041// support real time signals and simply seems to have just 331042// signals with no holes in the signal range.1043#if defined(__APPLE__)1044return sig >= 1 && sig < NSIG;1045#else1046// Use sigaddset to check for signal validity.1047sigset_t set;1048sigemptyset(&set);1049if (sigaddset(&set, sig) == -1 && errno == EINVAL) {1050return false;1051}1052return true;1053#endif1054}10551056static const char* get_signal_name(int sig, char* out, size_t outlen) {10571058const char* ret = NULL;10591060#ifdef SIGRTMIN1061if (sig >= SIGRTMIN && sig <= SIGRTMAX) {1062if (sig == SIGRTMIN) {1063ret = "SIGRTMIN";1064} else if (sig == SIGRTMAX) {1065ret = "SIGRTMAX";1066} else {1067jio_snprintf(out, outlen, "SIGRTMIN+%d", sig - SIGRTMIN);1068return out;1069}1070}1071#endif10721073if (sig > 0) {1074for (int idx = 0; g_signal_info[idx].sig != -1; idx ++) {1075if (g_signal_info[idx].sig == sig) {1076ret = g_signal_info[idx].name;1077break;1078}1079}1080}10811082if (!ret) {1083if (!is_valid_signal(sig)) {1084ret = "INVALID";1085} else {1086ret = "UNKNOWN";1087}1088}10891090if (out && outlen > 0) {1091strncpy(out, ret, outlen);1092out[outlen - 1] = '\0';1093}1094return out;1095}10961097void os::print_siginfo(outputStream* os, const void* si0) {10981099const siginfo_t* const si = (const siginfo_t*) si0;11001101char buf[20];1102os->print("siginfo:");11031104if (!si) {1105os->print(" <null>");1106return;1107}11081109const int sig = si->si_signo;11101111os->print(" si_signo: %d (%s)", sig, get_signal_name(sig, buf, sizeof(buf)));11121113enum_sigcode_desc_t ed;1114get_signal_code_description(si, &ed);1115os->print(", si_code: %d (%s)", si->si_code, ed.s_name);11161117if (si->si_errno) {1118os->print(", si_errno: %d", si->si_errno);1119}11201121// Output additional information depending on the signal code.11221123// Note: Many implementations lump si_addr, si_pid, si_uid etc. together as unions,1124// so it depends on the context which member to use. For synchronous error signals,1125// we print si_addr, unless the signal was sent by another process or thread, in1126// which case we print out pid or tid of the sender.1127if (os::signal_sent_by_kill(si)) {1128const pid_t pid = si->si_pid;1129os->print(", si_pid: %ld", (long) pid);1130if (IS_VALID_PID(pid)) {1131const pid_t me = getpid();1132if (me == pid) {1133os->print(" (current process)");1134}1135} else {1136os->print(" (invalid)");1137}1138os->print(", si_uid: %ld", (long) si->si_uid);1139if (sig == SIGCHLD) {1140os->print(", si_status: %d", si->si_status);1141}1142} else if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||1143sig == SIGTRAP || sig == SIGFPE) {1144os->print(", si_addr: " PTR_FORMAT, p2i(si->si_addr));1145#ifdef SIGPOLL1146} else if (sig == SIGPOLL) {1147os->print(", si_band: %ld", si->si_band);1148#endif1149}1150}11511152bool os::signal_thread(Thread* thread, int sig, const char* reason) {1153OSThread* osthread = thread->osthread();1154if (osthread) {1155int status = pthread_kill(osthread->pthread_id(), sig);1156if (status == 0) {1157Events::log(Thread::current(), "sent signal %d to Thread " INTPTR_FORMAT " because %s.",1158sig, p2i(thread), reason);1159return true;1160}1161}1162return false;1163}11641165// Returns:1166// NULL for an invalid signal number1167// "SIG<num>" for a valid but unknown signal number1168// signal name otherwise.1169const char* os::exception_name(int sig, char* buf, size_t size) {1170if (!is_valid_signal(sig)) {1171return NULL;1172}1173const char* const name = get_signal_name(sig, buf, size);1174if (strcmp(name, "UNKNOWN") == 0) {1175jio_snprintf(buf, size, "SIG%d", sig);1176}1177return buf;1178}11791180int os::get_signal_number(const char* signal_name) {1181char tmp[30];1182const char* s = signal_name;1183if (s[0] != 'S' || s[1] != 'I' || s[2] != 'G') {1184jio_snprintf(tmp, sizeof(tmp), "SIG%s", signal_name);1185s = tmp;1186}1187for (int idx = 0; g_signal_info[idx].sig != -1; idx ++) {1188if (strcmp(g_signal_info[idx].name, s) == 0) {1189return g_signal_info[idx].sig;1190}1191}1192return -1;1193}11941195void set_signal_handler(int sig) {1196// Check for overwrite.1197struct sigaction oldAct;1198sigaction(sig, (struct sigaction*)NULL, &oldAct);11991200// Query the current signal handler. Needs to be a separate operation1201// from installing a new handler since we need to honor AllowUserSignalHandlers.1202void* oldhand = get_signal_handler(&oldAct);1203if (!HANDLER_IS_IGN_OR_DFL(oldhand) &&1204!HANDLER_IS(oldhand, javaSignalHandler)) {1205if (AllowUserSignalHandlers) {1206// Do not overwrite; user takes responsibility to forward to us.1207return;1208} else if (UseSignalChaining) {1209// save the old handler in jvm1210chained_handlers.set(sig, &oldAct);1211// libjsig also interposes the sigaction() call below and saves the1212// old sigaction on it own.1213} else {1214fatal("Encountered unexpected pre-existing sigaction handler "1215"%#lx for signal %d.", (long)oldhand, sig);1216}1217}12181219struct sigaction sigAct;1220sigfillset(&(sigAct.sa_mask));1221remove_error_signals_from_set(&(sigAct.sa_mask));1222sigAct.sa_sigaction = javaSignalHandler;1223sigAct.sa_flags = SA_SIGINFO|SA_RESTART;1224#if defined(__APPLE__)1225// Needed for main thread as XNU (Mac OS X kernel) will only deliver SIGSEGV1226// (which starts as SIGBUS) on main thread with faulting address inside "stack+guard pages"1227// if the signal handler declares it will handle it on alternate stack.1228// Notice we only declare we will handle it on alt stack, but we are not1229// actually going to use real alt stack - this is just a workaround.1230// Please see ux_exception.c, method catch_mach_exception_raise for details1231// link http://www.opensource.apple.com/source/xnu/xnu-2050.18.24/bsd/uxkern/ux_exception.c1232if (sig == SIGSEGV) {1233sigAct.sa_flags |= SA_ONSTACK;1234}1235#endif12361237// Save handler setup for later checking1238vm_handlers.set(sig, &sigAct);1239do_check_signal_periodically[sig] = true;12401241int ret = sigaction(sig, &sigAct, &oldAct);1242assert(ret == 0, "check");12431244void* oldhand2 = get_signal_handler(&oldAct);1245assert(oldhand2 == oldhand, "no concurrent signal handler installation");1246}12471248// install signal handlers for signals that HotSpot needs to1249// handle in order to support Java-level exception handling.1250void install_signal_handlers() {1251// signal-chaining1252typedef void (*signal_setting_t)();1253signal_setting_t begin_signal_setting = NULL;1254signal_setting_t end_signal_setting = NULL;1255begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,1256dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));1257if (begin_signal_setting != NULL) {1258end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,1259dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));1260get_signal_action = CAST_TO_FN_PTR(get_signal_t,1261dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));1262libjsig_is_loaded = true;1263assert(UseSignalChaining, "should enable signal-chaining");1264}1265if (libjsig_is_loaded) {1266// Tell libjsig jvm is setting signal handlers1267(*begin_signal_setting)();1268}12691270set_signal_handler(SIGSEGV);1271set_signal_handler(SIGPIPE);1272set_signal_handler(SIGBUS);1273set_signal_handler(SIGILL);1274set_signal_handler(SIGFPE);1275PPC64_ONLY(set_signal_handler(SIGTRAP);)1276set_signal_handler(SIGXFSZ);12771278#if defined(__APPLE__)1279// lldb (gdb) installs both standard BSD signal handlers, and mach exception1280// handlers. By replacing the existing task exception handler, we disable lldb's mach1281// exception handling, while leaving the standard BSD signal handlers functional.1282//1283// EXC_MASK_BAD_ACCESS needed by all architectures for NULL ptr checking1284// EXC_MASK_ARITHMETIC needed by all architectures for div by 0 checking1285// EXC_MASK_BAD_INSTRUCTION needed by aarch64 to initiate deoptimization1286kern_return_t kr;1287kr = task_set_exception_ports(mach_task_self(),1288EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC1289AARCH64_ONLY(| EXC_MASK_BAD_INSTRUCTION),1290MACH_PORT_NULL,1291EXCEPTION_STATE_IDENTITY,1292MACHINE_THREAD_STATE);12931294assert(kr == KERN_SUCCESS, "could not set mach task signal handler");1295#endif12961297if (libjsig_is_loaded) {1298// Tell libjsig jvm finishes setting signal handlers1299(*end_signal_setting)();1300}13011302// We don't activate signal checker if libjsig is in place, we trust ourselves1303// and if UserSignalHandler is installed all bets are off.1304// Log that signal checking is off only if -verbose:jni is specified.1305if (CheckJNICalls) {1306if (libjsig_is_loaded) {1307log_debug(jni, resolve)("Info: libjsig is activated, all active signal checking is disabled");1308check_signals = false;1309}1310if (AllowUserSignalHandlers) {1311log_debug(jni, resolve)("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");1312check_signals = false;1313}1314}1315}13161317// Returns one-line short description of a signal set in a user provided buffer.1318static const char* describe_signal_set_short(const sigset_t* set, char* buffer, size_t buf_size) {1319assert(buf_size == (NUM_IMPORTANT_SIGS + 1), "wrong buffer size");1320// Note: for shortness, just print out the first 32. That should1321// cover most of the useful ones, apart from realtime signals.1322for (int sig = 1; sig <= NUM_IMPORTANT_SIGS; sig++) {1323const int rc = sigismember(set, sig);1324if (rc == -1 && errno == EINVAL) {1325buffer[sig-1] = '?';1326} else {1327buffer[sig-1] = rc == 0 ? '0' : '1';1328}1329}1330buffer[NUM_IMPORTANT_SIGS] = 0;1331return buffer;1332}13331334// Prints one-line description of a signal set.1335static void print_signal_set_short(outputStream* st, const sigset_t* set) {1336char buf[NUM_IMPORTANT_SIGS + 1];1337describe_signal_set_short(set, buf, sizeof(buf));1338st->print("%s", buf);1339}13401341static void print_single_signal_handler(outputStream* st,1342const struct sigaction* act,1343char* buf, size_t buflen) {13441345address handler = get_signal_handler(act);1346if (HANDLER_IS_DFL(handler)) {1347st->print("SIG_DFL");1348} else if (HANDLER_IS_IGN(handler)) {1349st->print("SIG_IGN");1350} else {1351print_signal_handler_name(st, handler, buf, buflen);1352}13531354st->print(", mask=");1355print_signal_set_short(st, &(act->sa_mask));13561357st->print(", flags=");1358int flags = get_sanitized_sa_flags(act);1359print_sa_flags(st, flags);13601361}13621363// Print established signal handler for this signal.1364// - if this signal handler was installed by us and is chained to a pre-established user handler1365// it replaced, print that one too.1366// - otherwise, if this signal handler was installed by us and replaced another handler to which we1367// are not chained (e.g. if chaining is off), print that one too.1368void PosixSignals::print_signal_handler(outputStream* st, int sig,1369char* buf, size_t buflen) {13701371st->print("%10s: ", os::exception_name(sig, buf, buflen));13721373struct sigaction current_act;1374sigaction(sig, NULL, ¤t_act);13751376print_single_signal_handler(st, ¤t_act, buf, buflen);1377st->cr();13781379// If we expected to see our own hotspot signal handler but found a different one,1380// print a warning (unless the handler replacing it is our own crash handler, which can1381// happen if this function is called during error reporting).1382const struct sigaction* expected_act = vm_handlers.get(sig);1383if (expected_act != NULL) {1384const address current_handler = get_signal_handler(¤t_act);1385if (!(HANDLER_IS(current_handler, VMError::crash_handler_address))) {1386if (!are_handlers_equal(¤t_act, expected_act)) {1387st->print_cr(" *** Handler was modified!");1388st->print (" *** Expected: ");1389print_single_signal_handler(st, expected_act, buf, buflen);1390st->cr();1391}1392}1393}13941395// If there is a chained handler waiting behind the current one, print it too.1396const struct sigaction* chained_act = get_chained_signal_action(sig);1397if (chained_act != NULL) {1398st->print(" chained to: ");1399print_single_signal_handler(st, ¤t_act, buf, buflen);1400st->cr();1401}1402}14031404void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {1405st->print_cr("Signal Handlers:");1406PosixSignals::print_signal_handler(st, SIGSEGV, buf, buflen);1407PosixSignals::print_signal_handler(st, SIGBUS , buf, buflen);1408PosixSignals::print_signal_handler(st, SIGFPE , buf, buflen);1409PosixSignals::print_signal_handler(st, SIGPIPE, buf, buflen);1410PosixSignals::print_signal_handler(st, SIGXFSZ, buf, buflen);1411PosixSignals::print_signal_handler(st, SIGILL , buf, buflen);1412PosixSignals::print_signal_handler(st, PosixSignals::SR_signum, buf, buflen);1413PosixSignals::print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);1414PosixSignals::print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);1415PosixSignals::print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);1416PosixSignals::print_signal_handler(st, BREAK_SIGNAL, buf, buflen);1417#if defined(SIGDANGER)1418// We also want to know if someone else adds a SIGDANGER handler because1419// that will interfere with OOM killling.1420PosixSignals::print_signal_handler(st, SIGDANGER, buf, buflen);1421#endif1422#if defined(SIGTRAP)1423PosixSignals::print_signal_handler(st, SIGTRAP, buf, buflen);1424#endif1425}14261427bool PosixSignals::is_sig_ignored(int sig) {1428struct sigaction oact;1429sigaction(sig, (struct sigaction*)NULL, &oact);1430if (HANDLER_IS_IGN(get_signal_handler(&oact))) {1431return true;1432} else {1433return false;1434}1435}14361437static void signal_sets_init() {1438sigemptyset(&preinstalled_sigs);14391440// Should also have an assertion stating we are still single-threaded.1441assert(!signal_sets_initialized, "Already initialized");1442// Fill in signals that are necessarily unblocked for all threads in1443// the VM. Currently, we unblock the following signals:1444// SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden1445// by -Xrs (=ReduceSignalUsage));1446// BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all1447// other threads. The "ReduceSignalUsage" boolean tells us not to alter1448// the dispositions or masks wrt these signals.1449// Programs embedding the VM that want to use the above signals for their1450// own purposes must, at this time, use the "-Xrs" option to prevent1451// interference with shutdown hooks and BREAK_SIGNAL thread dumping.1452// (See bug 4345157, and other related bugs).1453// In reality, though, unblocking these signals is really a nop, since1454// these signals are not blocked by default.1455sigemptyset(&unblocked_sigs);1456sigaddset(&unblocked_sigs, SIGILL);1457sigaddset(&unblocked_sigs, SIGSEGV);1458sigaddset(&unblocked_sigs, SIGBUS);1459sigaddset(&unblocked_sigs, SIGFPE);1460PPC64_ONLY(sigaddset(&unblocked_sigs, SIGTRAP);)1461sigaddset(&unblocked_sigs, PosixSignals::SR_signum);14621463if (!ReduceSignalUsage) {1464if (!PosixSignals::is_sig_ignored(SHUTDOWN1_SIGNAL)) {1465sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);1466}1467if (!PosixSignals::is_sig_ignored(SHUTDOWN2_SIGNAL)) {1468sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);1469}1470if (!PosixSignals::is_sig_ignored(SHUTDOWN3_SIGNAL)) {1471sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);1472}1473}1474// Fill in signals that are blocked by all but the VM thread.1475sigemptyset(&vm_sigs);1476if (!ReduceSignalUsage) {1477sigaddset(&vm_sigs, BREAK_SIGNAL);1478}1479debug_only(signal_sets_initialized = true);1480}14811482// These are signals that are unblocked while a thread is running Java.1483// (For some reason, they get blocked by default.)1484static sigset_t* unblocked_signals() {1485assert(signal_sets_initialized, "Not initialized");1486return &unblocked_sigs;1487}14881489// These are the signals that are blocked while a (non-VM) thread is1490// running Java. Only the VM thread handles these signals.1491static sigset_t* vm_signals() {1492assert(signal_sets_initialized, "Not initialized");1493return &vm_sigs;1494}14951496void PosixSignals::hotspot_sigmask(Thread* thread) {14971498//Save caller's signal mask before setting VM signal mask1499sigset_t caller_sigmask;1500pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask);15011502OSThread* osthread = thread->osthread();1503osthread->set_caller_sigmask(caller_sigmask);15041505pthread_sigmask(SIG_UNBLOCK, unblocked_signals(), NULL);15061507if (!ReduceSignalUsage) {1508if (thread->is_VM_thread()) {1509// Only the VM thread handles BREAK_SIGNAL ...1510pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL);1511} else {1512// ... all other threads block BREAK_SIGNAL1513pthread_sigmask(SIG_BLOCK, vm_signals(), NULL);1514}1515}1516}15171518////////////////////////////////////////////////////////////////////////////////1519// suspend/resume support15201521// The low-level signal-based suspend/resume support is a remnant from the1522// old VM-suspension that used to be for java-suspension, safepoints etc,1523// within hotspot. Currently used by JFR's OSThreadSampler1524//1525// The remaining code is greatly simplified from the more general suspension1526// code that used to be used.1527//1528// The protocol is quite simple:1529// - suspend:1530// - sends a signal to the target thread1531// - polls the suspend state of the osthread using a yield loop1532// - target thread signal handler (SR_handler) sets suspend state1533// and blocks in sigsuspend until continued1534// - resume:1535// - sets target osthread state to continue1536// - sends signal to end the sigsuspend loop in the SR_handler1537//1538// Note that resume_clear_context() and suspend_save_context() are needed1539// by SR_handler(), so that fetch_frame_from_context() works,1540// which in part is used by:1541// - Forte Analyzer: AsyncGetCallTrace()1542// - StackBanging: get_frame_at_stack_banging_point()15431544sigset_t SR_sigset;15451546static void resume_clear_context(OSThread *osthread) {1547osthread->set_ucontext(NULL);1548osthread->set_siginfo(NULL);1549}15501551static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {1552osthread->set_ucontext(context);1553osthread->set_siginfo(siginfo);1554}15551556// Handler function invoked when a thread's execution is suspended or1557// resumed. We have to be careful that only async-safe functions are1558// called here (Note: most pthread functions are not async safe and1559// should be avoided.)1560//1561// Note: sigwait() is a more natural fit than sigsuspend() from an1562// interface point of view, but sigwait() prevents the signal handler1563// from being run. libpthread would get very confused by not having1564// its signal handlers run and prevents sigwait()'s use with the1565// mutex granting signal.1566//1567// Currently only ever called on the VMThread and JavaThreads (PC sampling)1568//1569static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {15701571// Save and restore errno to avoid confusing native code with EINTR1572// after sigsuspend.1573int old_errno = errno;15741575PosixSignals::unblock_error_signals();15761577Thread* thread = Thread::current_or_null_safe();1578assert(thread != NULL, "Missing current thread in SR_handler");15791580// On some systems we have seen signal delivery get "stuck" until the signal1581// mask is changed as part of thread termination. Check that the current thread1582// has not already terminated - else the following assertion1583// will fail because the thread is no longer a JavaThread as the ~JavaThread1584// destructor has completed.15851586if (thread->has_terminated()) {1587return;1588}15891590assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");15911592OSThread* osthread = thread->osthread();15931594os::SuspendResume::State current = osthread->sr.state();15951596if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {1597suspend_save_context(osthread, siginfo, context);15981599// attempt to switch the state, we assume we had a SUSPEND_REQUEST1600os::SuspendResume::State state = osthread->sr.suspended();1601if (state == os::SuspendResume::SR_SUSPENDED) {1602sigset_t suspend_set; // signals for sigsuspend()1603sigemptyset(&suspend_set);16041605// get current set of blocked signals and unblock resume signal1606pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);1607sigdelset(&suspend_set, PosixSignals::SR_signum);16081609sr_semaphore.signal();16101611// wait here until we are resumed1612while (1) {1613sigsuspend(&suspend_set);16141615os::SuspendResume::State result = osthread->sr.running();1616if (result == os::SuspendResume::SR_RUNNING) {1617// double check AIX doesn't need this!1618sr_semaphore.signal();1619break;1620} else if (result != os::SuspendResume::SR_SUSPENDED) {1621ShouldNotReachHere();1622}1623}16241625} else if (state == os::SuspendResume::SR_RUNNING) {1626// request was cancelled, continue1627} else {1628ShouldNotReachHere();1629}16301631resume_clear_context(osthread);1632} else if (current == os::SuspendResume::SR_RUNNING) {1633// request was cancelled, continue1634} else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {1635// ignore1636} else {1637// ignore1638}16391640errno = old_errno;1641}16421643int SR_initialize() {1644struct sigaction act;1645char *s;1646// Get signal number to use for suspend/resume1647if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {1648int sig = ::strtol(s, 0, 10);1649if (sig > MAX2(SIGSEGV, SIGBUS) && // See 4355769.1650sig < NSIG) { // Must be legal signal and fit into sigflags[].1651PosixSignals::SR_signum = sig;1652} else {1653warning("You set _JAVA_SR_SIGNUM=%d. It must be in range [%d, %d]. Using %d instead.",1654sig, MAX2(SIGSEGV, SIGBUS)+1, NSIG-1, PosixSignals::SR_signum);1655}1656}16571658assert(PosixSignals::SR_signum > SIGSEGV && PosixSignals::SR_signum > SIGBUS,1659"SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");16601661sigemptyset(&SR_sigset);1662sigaddset(&SR_sigset, PosixSignals::SR_signum);16631664// Set up signal handler for suspend/resume1665act.sa_flags = SA_RESTART|SA_SIGINFO;1666act.sa_handler = (void (*)(int)) SR_handler;16671668// SR_signum is blocked by default.1669pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask);1670remove_error_signals_from_set(&(act.sa_mask));16711672if (sigaction(PosixSignals::SR_signum, &act, 0) == -1) {1673return -1;1674}16751676// Save signal setup information for later checking.1677vm_handlers.set(PosixSignals::SR_signum, &act);1678do_check_signal_periodically[PosixSignals::SR_signum] = true;16791680return 0;1681}16821683static int sr_notify(OSThread* osthread) {1684int status = pthread_kill(osthread->pthread_id(), PosixSignals::SR_signum);1685assert_status(status == 0, status, "pthread_kill");1686return status;1687}16881689// returns true on success and false on error - really an error is fatal1690// but this seems the normal response to library errors1691bool PosixSignals::do_suspend(OSThread* osthread) {1692assert(osthread->sr.is_running(), "thread should be running");1693assert(!sr_semaphore.trywait(), "semaphore has invalid state");16941695// mark as suspended and send signal1696if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {1697// failed to switch, state wasn't running?1698ShouldNotReachHere();1699return false;1700}17011702if (sr_notify(osthread) != 0) {1703ShouldNotReachHere();1704}17051706// managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED1707while (true) {1708if (sr_semaphore.timedwait(2)) {1709break;1710} else {1711// timeout1712os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();1713if (cancelled == os::SuspendResume::SR_RUNNING) {1714return false;1715} else if (cancelled == os::SuspendResume::SR_SUSPENDED) {1716// make sure that we consume the signal on the semaphore as well1717sr_semaphore.wait();1718break;1719} else {1720ShouldNotReachHere();1721return false;1722}1723}1724}17251726guarantee(osthread->sr.is_suspended(), "Must be suspended");1727return true;1728}17291730void PosixSignals::do_resume(OSThread* osthread) {1731assert(osthread->sr.is_suspended(), "thread should be suspended");1732assert(!sr_semaphore.trywait(), "invalid semaphore state");17331734if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {1735// failed to switch to WAKEUP_REQUEST1736ShouldNotReachHere();1737return;1738}17391740while (true) {1741if (sr_notify(osthread) == 0) {1742if (sr_semaphore.timedwait(2)) {1743if (osthread->sr.is_running()) {1744return;1745}1746}1747} else {1748ShouldNotReachHere();1749}1750}17511752guarantee(osthread->sr.is_running(), "Must be running!");1753}17541755void os::SuspendedThreadTask::internal_do_task() {1756if (PosixSignals::do_suspend(_thread->osthread())) {1757os::SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());1758do_task(context);1759PosixSignals::do_resume(_thread->osthread());1760}1761}17621763int PosixSignals::init() {1764// initialize suspend/resume support - must do this before signal_sets_init()1765if (SR_initialize() != 0) {1766vm_exit_during_initialization("SR_initialize failed");1767return JNI_ERR;1768}17691770signal_sets_init();17711772install_signal_handlers();17731774// Initialize data for jdk.internal.misc.Signal1775if (!ReduceSignalUsage) {1776jdk_misc_signal_init();1777}17781779return JNI_OK;1780}178117821783