# HG changeset patch # User goetz # Date 1446732359 -3600 # Node ID f8097485b483552d6435e37214fe948fb273c030 # Parent b181699c6616dcc8af4a51bae15ad7722029be42 8141529: Fix handling of _JAVA_SR_SIGNUM Reviewed-by: dholmes, stuefe, dsamersoff diff -r b181699c6616 -r f8097485b483 hotspot/src/os/aix/vm/jsig.c --- a/hotspot/src/os/aix/vm/jsig.c Mon Nov 16 18:50:55 2015 -0500 +++ b/hotspot/src/os/aix/vm/jsig.c Thu Nov 05 15:05:59 2015 +0100 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2013 SAP AG. All rights reserved. + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2015 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,26 +36,23 @@ #include #include #include +#include #define bool int #define true 1 #define false 0 -// Highest so far on AIX 5.2 is SIGSAK (63) -#define MAXSIGNUM 63 -#define MASK(sig) ((unsigned int)1 << sig) +static struct sigaction sact[NSIG]; /* saved signal handlers */ +static sigset_t jvmsigs; /* Signals used by jvm. */ -static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ -static unsigned int jvmsigs = 0; /* signals used by jvm */ - -/* used to synchronize the installation of signal handlers */ +/* Used to synchronize the installation of signal handlers. */ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; static pthread_t tid = 0; typedef void (*sa_handler_t)(int); typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); -// signal_t is already defined on AIX +// signal_t is already defined on AIX. typedef sa_handler_t (*signal_like_function_t)(int, sa_handler_t); typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *); @@ -68,7 +65,7 @@ static void signal_lock() { pthread_mutex_lock(&mutex); /* When the jvm is installing its set of signal handlers, threads - * other than the jvm thread should wait */ + * other than the jvm thread should wait. */ if (jvm_signal_installing) { if (tid != pthread_self()) { pthread_cond_wait(&cond, &mutex); @@ -84,10 +81,10 @@ bool is_sigset) { if (os_signal == NULL) { if (!is_sigset) { - // Aix: call functions directly instead of dlsym'ing them + // Aix: call functions directly instead of dlsym'ing them. os_signal = signal; } else { - // Aix: call functions directly instead of dlsym'ing them + // Aix: call functions directly instead of dlsym'ing them. os_signal = sigset; } if (os_signal == NULL) { @@ -112,7 +109,7 @@ signal_lock(); - sigused = (MASK(sig) & jvmsigs) != 0; + sigused = sigismember(&jvmsigs, sig); if (jvm_signal_installed && sigused) { /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ @@ -129,7 +126,7 @@ save_signal_handler(sig, oldhandler); /* Record the signals used by jvm */ - jvmsigs |= MASK(sig); + sigaddset(&jvmsigs, sig); signal_unlock(); return oldhandler; @@ -149,12 +146,12 @@ sa_handler_t sigset(int sig, sa_handler_t disp) { return set_signal(sig, disp, true); - } +} static int call_os_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { if (os_sigaction == NULL) { - // Aix: call functions directly instead of dlsym'ing them + // Aix: call functions directly instead of dlsym'ing them. os_sigaction = sigaction; if (os_sigaction == NULL) { printf("%s\n", dlerror()); @@ -171,7 +168,7 @@ signal_lock(); - sigused = (MASK(sig) & jvmsigs) != 0; + sigused = sigismember(&jvmsigs, sig); if (jvm_signal_installed && sigused) { /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ @@ -193,8 +190,8 @@ *oact = oldAct; } - /* Record the signals used by jvm */ - jvmsigs |= MASK(sig); + /* Record the signals used by jvm. */ + sigaddset(&jvmsigs, sig); signal_unlock(); return res; @@ -208,9 +205,10 @@ } } -/* The three functions for the jvm to call into */ +/* The three functions for the jvm to call into. */ void JVM_begin_signal_setting() { signal_lock(); + sigemptyset(&jvmsigs); jvm_signal_installing = true; tid = pthread_self(); signal_unlock(); @@ -226,7 +224,7 @@ struct sigaction *JVM_get_signal_action(int sig) { /* Does race condition make sense here? */ - if ((MASK(sig) & jvmsigs) != 0) { + if (sigismember(&jvmsigs, sig)) { return &sact[sig]; } return NULL; diff -r b181699c6616 -r f8097485b483 hotspot/src/os/aix/vm/os_aix.cpp --- a/hotspot/src/os/aix/vm/os_aix.cpp Mon Nov 16 18:50:55 2015 -0500 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Thu Nov 05 15:05:59 2015 +0100 @@ -2769,8 +2769,12 @@ // Get signal number to use for suspend/resume if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { int sig = ::strtol(s, 0, 10); - if (sig > 0 || sig < NSIG) { + if (sig > MAX2(SIGSEGV, SIGBUS) && // See 4355769. + sig < NSIG) { // Must be legal signal and fit into sigflags[]. SR_signum = sig; + } else { + warning("You set _JAVA_SR_SIGNUM=%d. It must be in range [%d, %d]. Using %d instead.", + sig, MAX2(SIGSEGV, SIGBUS)+1, NSIG-1, SR_signum); } } @@ -2966,8 +2970,8 @@ bool os::Aix::signal_handlers_are_installed = false; // For signal-chaining -struct sigaction os::Aix::sigact[MAXSIGNUM]; -unsigned int os::Aix::sigs = 0; +struct sigaction sigact[NSIG]; +sigset_t sigs; bool os::Aix::libjsig_is_loaded = false; typedef struct sigaction *(*get_signal_t)(int); get_signal_t os::Aix::get_signal_action = NULL; @@ -3045,29 +3049,31 @@ } struct sigaction* os::Aix::get_preinstalled_handler(int sig) { - if ((((unsigned int)1 << sig) & sigs) != 0) { + if (sigismember(&sigs, sig)) { return &sigact[sig]; } return NULL; } void os::Aix::save_preinstalled_handler(int sig, struct sigaction& oldAct) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); sigact[sig] = oldAct; - sigs |= (unsigned int)1 << sig; + sigaddset(&sigs, sig); } // for diagnostic -int os::Aix::sigflags[MAXSIGNUM]; +int sigflags[NSIG]; int os::Aix::get_our_sigflags(int sig) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); return sigflags[sig]; } void os::Aix::set_our_sigflags(int sig, int flags) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); - sigflags[sig] = flags; + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); + if (sig > 0 && sig < NSIG) { + sigflags[sig] = flags; + } } void os::Aix::set_signal_handler(int sig, bool set_installed) { @@ -3107,7 +3113,7 @@ sigAct.sa_flags = SA_SIGINFO|SA_RESTART; } // Save flags, which are set by ours - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); sigflags[sig] = sigAct.sa_flags; int ret = sigaction(sig, &sigAct, &oldAct); @@ -3140,10 +3146,11 @@ assert(UseSignalChaining, "should enable signal-chaining"); } if (libjsig_is_loaded) { - // Tell libjsig jvm is setting signal handlers + // Tell libjsig jvm is setting signal handlers. (*begin_signal_setting)(); } + ::sigemptyset(&sigs); set_signal_handler(SIGSEGV, true); set_signal_handler(SIGPIPE, true); set_signal_handler(SIGBUS, true); diff -r b181699c6616 -r f8097485b483 hotspot/src/os/aix/vm/os_aix.hpp --- a/hotspot/src/os/aix/vm/os_aix.hpp Mon Nov 16 18:50:55 2015 -0500 +++ b/hotspot/src/os/aix/vm/os_aix.hpp Thu Nov 05 15:05:59 2015 +0100 @@ -34,15 +34,9 @@ class Aix { friend class os; - // For signal-chaining - // highest so far (AIX 5.2 - 6.1) is SIGSAK (63) -#define MAXSIGNUM 63 // Length of strings included in the libperfstat structures. #define IDENTIFIER_LENGTH 64 - static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions - static unsigned int sigs; // mask of signals that have - // preinstalled signal handlers static bool libjsig_is_loaded; // libjsig that interposes sigaction(), // __sigaction(), signal() is loaded static struct sigaction *(*get_signal_action)(int); @@ -51,9 +45,6 @@ static void check_signal_handler(int sig); - // For signal flags diagnostics - static int sigflags[MAXSIGNUM]; - protected: static julong _physical_memory; diff -r b181699c6616 -r f8097485b483 hotspot/src/os/bsd/vm/jsig.c --- a/hotspot/src/os/bsd/vm/jsig.c Mon Nov 16 18:50:55 2015 -0500 +++ b/hotspot/src/os/bsd/vm/jsig.c Thu Nov 05 15:05:59 2015 +0100 @@ -36,12 +36,14 @@ #include #include #include +#include -#define MAXSIGNUM 32 -#define MASK(sig) ((unsigned int)1 << sig) - -static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ -static unsigned int jvmsigs = 0; /* signals used by jvm */ +#define MASK(sig) ((uint32_t)1 << (sig-1)) // 0 is not a signal. +#if (32 < NSIG-1) +#error "Not all signals can be encoded in jvmsigs. Adapt its type!" +#endif +static struct sigaction sact[NSIG]; /* saved signal handlers */ +static uint32_t jvmsigs = 0; /* signals used by jvm */ static __thread bool reentry = false; /* prevent reentry deadlock (per-thread) */ /* used to synchronize the installation of signal handlers */ diff -r b181699c6616 -r f8097485b483 hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Mon Nov 16 18:50:55 2015 -0500 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Nov 05 15:05:59 2015 +0100 @@ -2831,8 +2831,12 @@ // Get signal number to use for suspend/resume if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { int sig = ::strtol(s, 0, 10); - if (sig > 0 || sig < NSIG) { + if (sig > MAX2(SIGSEGV, SIGBUS) && // See 4355769. + sig < NSIG) { // Must be legal signal and fit into sigflags[]. SR_signum = sig; + } else { + warning("You set _JAVA_SR_SIGNUM=%d. It must be in range [%d, %d]. Using %d instead.", + sig, MAX2(SIGSEGV, SIGBUS)+1, NSIG-1, SR_signum); } } @@ -2985,8 +2989,11 @@ bool os::Bsd::signal_handlers_are_installed = false; // For signal-chaining -struct sigaction os::Bsd::sigact[MAXSIGNUM]; -unsigned int os::Bsd::sigs = 0; +struct sigaction sigact[NSIG]; +uint32_t sigs = 0; +#if (32 < NSIG-1) +#error "Not all signals can be encoded in sigs. Adapt its type!" +#endif bool os::Bsd::libjsig_is_loaded = false; typedef struct sigaction *(*get_signal_t)(int); get_signal_t os::Bsd::get_signal_action = NULL; @@ -3064,29 +3071,31 @@ } struct sigaction* os::Bsd::get_preinstalled_handler(int sig) { - if ((((unsigned int)1 << sig) & sigs) != 0) { + if ((((uint32_t)1 << (sig-1)) & sigs) != 0) { return &sigact[sig]; } return NULL; } void os::Bsd::save_preinstalled_handler(int sig, struct sigaction& oldAct) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); sigact[sig] = oldAct; - sigs |= (unsigned int)1 << sig; + sigs |= (uint32_t)1 << (sig-1); } // for diagnostic -int os::Bsd::sigflags[MAXSIGNUM]; +int sigflags[NSIG]; int os::Bsd::get_our_sigflags(int sig) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); return sigflags[sig]; } void os::Bsd::set_our_sigflags(int sig, int flags) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); - sigflags[sig] = flags; + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); + if (sig > 0 && sig < NSIG) { + sigflags[sig] = flags; + } } void os::Bsd::set_signal_handler(int sig, bool set_installed) { @@ -3137,7 +3146,7 @@ #endif // Save flags, which are set by ours - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); sigflags[sig] = sigAct.sa_flags; int ret = sigaction(sig, &sigAct, &oldAct); diff -r b181699c6616 -r f8097485b483 hotspot/src/os/bsd/vm/os_bsd.hpp --- a/hotspot/src/os/bsd/vm/os_bsd.hpp Mon Nov 16 18:50:55 2015 -0500 +++ b/hotspot/src/os/bsd/vm/os_bsd.hpp Thu Nov 05 15:05:59 2015 +0100 @@ -40,10 +40,6 @@ friend class os; // For signal-chaining -#define MAXSIGNUM 32 - static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions - static unsigned int sigs; // mask of signals that have - // preinstalled signal handlers static bool libjsig_is_loaded; // libjsig that interposes sigaction(), // __sigaction(), signal() is loaded static struct sigaction *(*get_signal_action)(int); @@ -52,9 +48,6 @@ static void check_signal_handler(int sig); - // For signal flags diagnostics - static int sigflags[MAXSIGNUM]; - #ifdef __APPLE__ // mach_absolute_time static mach_timebase_info_data_t _timebase_info; diff -r b181699c6616 -r f8097485b483 hotspot/src/os/linux/vm/jsig.c --- a/hotspot/src/os/linux/vm/jsig.c Mon Nov 16 18:50:55 2015 -0500 +++ b/hotspot/src/os/linux/vm/jsig.c Thu Nov 05 15:05:59 2015 +0100 @@ -35,16 +35,19 @@ #include #include #include +#include #define bool int #define true 1 #define false 0 -#define MAXSIGNUM 32 -#define MASK(sig) ((unsigned int)1 << sig) - -static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ -static unsigned int jvmsigs = 0; /* signals used by jvm */ +#define MASK(sig) ((uint64_t)1 << (sig-1)) // 0 is not a signal. +// Check whether all signals fit into jvmsigs. -1 as MASK shifts by -1. +#if (64 < NSIG-1) +#error "Not all signals can be encoded in jvmsigs. Adapt its type!" +#endif +static struct sigaction sact[NSIG]; /* saved signal handlers */ +static uint64_t jvmsigs = 0; /* signals used by jvm */ /* used to synchronize the installation of signal handlers */ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; @@ -107,7 +110,7 @@ signal_lock(); - sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0); + sigused = (sig < NSIG) && ((MASK(sig) & jvmsigs) != 0); if (jvm_signal_installed && sigused) { /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ @@ -116,7 +119,7 @@ signal_unlock(); return oldhandler; - } else if (sig < MAXSIGNUM && jvm_signal_installing) { + } else if (sig < NSIG && jvm_signal_installing) { /* jvm is installing its signal handlers. Install the new * handlers and save the old ones. jvm uses sigaction(). * Leave the piece here just in case. */ @@ -165,7 +168,7 @@ signal_lock(); - sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0); + sigused = (sig < NSIG) && ((MASK(sig) & jvmsigs) != 0); if (jvm_signal_installed && sigused) { /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ @@ -178,7 +181,7 @@ signal_unlock(); return 0; - } else if (sig < MAXSIGNUM && jvm_signal_installing) { + } else if (sig < NSIG && jvm_signal_installing) { /* jvm is installing its signal handlers. Install the new * handlers and save the old ones. */ res = call_os_sigaction(sig, act, &oldAct); diff -r b181699c6616 -r f8097485b483 hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Mon Nov 16 18:50:55 2015 -0500 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu Nov 05 15:05:59 2015 +0100 @@ -3989,15 +3989,19 @@ errno = old_errno; } - static int SR_initialize() { struct sigaction act; char *s; + // Get signal number to use for suspend/resume if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { int sig = ::strtol(s, 0, 10); - if (sig > 0 || sig < _NSIG) { + if (sig > MAX2(SIGSEGV, SIGBUS) && // See 4355769. + sig < NSIG) { // Must be legal signal and fit into sigflags[]. SR_signum = sig; + } else { + warning("You set _JAVA_SR_SIGNUM=%d. It must be in range [%d, %d]. Using %d instead.", + sig, MAX2(SIGSEGV, SIGBUS)+1, NSIG-1, SR_signum); } } @@ -4151,8 +4155,11 @@ bool os::Linux::signal_handlers_are_installed = false; // For signal-chaining -struct sigaction os::Linux::sigact[MAXSIGNUM]; -unsigned int os::Linux::sigs = 0; +struct sigaction sigact[NSIG]; +uint64_t sigs = 0; +#if (64 < NSIG-1) +#error "Not all signals can be encoded in sigs. Adapt its type!" +#endif bool os::Linux::libjsig_is_loaded = false; typedef struct sigaction *(*get_signal_t)(int); get_signal_t os::Linux::get_signal_action = NULL; @@ -4230,29 +4237,29 @@ } struct sigaction* os::Linux::get_preinstalled_handler(int sig) { - if ((((unsigned int)1 << sig) & sigs) != 0) { + if ((((uint64_t)1 << (sig-1)) & sigs) != 0) { return &sigact[sig]; } return NULL; } void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); sigact[sig] = oldAct; - sigs |= (unsigned int)1 << sig; + sigs |= (uint64_t)1 << (sig-1); } // for diagnostic -int os::Linux::sigflags[MAXSIGNUM]; +int sigflags[NSIG]; int os::Linux::get_our_sigflags(int sig) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); return sigflags[sig]; } void os::Linux::set_our_sigflags(int sig, int flags) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); - if (sig > 0 && sig < MAXSIGNUM) { + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); + if (sig > 0 && sig < NSIG) { sigflags[sig] = flags; } } @@ -4292,7 +4299,7 @@ sigAct.sa_flags = SA_SIGINFO|SA_RESTART; } // Save flags, which are set by ours - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); sigflags[sig] = sigAct.sa_flags; int ret = sigaction(sig, &sigAct, &oldAct); diff -r b181699c6616 -r f8097485b483 hotspot/src/os/linux/vm/os_linux.hpp --- a/hotspot/src/os/linux/vm/os_linux.hpp Mon Nov 16 18:50:55 2015 -0500 +++ b/hotspot/src/os/linux/vm/os_linux.hpp Thu Nov 05 15:05:59 2015 +0100 @@ -34,11 +34,6 @@ friend class os; friend class TestReserveMemorySpecial; - // For signal-chaining -#define MAXSIGNUM 32 - static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions - static unsigned int sigs; // mask of signals that have - // preinstalled signal handlers static bool libjsig_is_loaded; // libjsig that interposes sigaction(), // __sigaction(), signal() is loaded static struct sigaction *(*get_signal_action)(int); @@ -47,9 +42,6 @@ static void check_signal_handler(int sig); - // For signal flags diagnostics - static int sigflags[MAXSIGNUM]; - static int (*_clock_gettime)(clockid_t, struct timespec *); static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *); static int (*_pthread_setname_np)(pthread_t, const char*); diff -r b181699c6616 -r f8097485b483 hotspot/src/os/solaris/vm/os_solaris.hpp --- a/hotspot/src/os/solaris/vm/os_solaris.hpp Mon Nov 16 18:50:55 2015 -0500 +++ b/hotspot/src/os/solaris/vm/os_solaris.hpp Thu Nov 05 15:05:59 2015 +0100 @@ -113,9 +113,6 @@ static void try_enable_extended_io(); - // For signal-chaining - static unsigned long sigs; // mask of signals that have - // preinstalled signal handlers static struct sigaction *(*get_signal_action)(int); static struct sigaction *get_preinstalled_handler(int); static int (*get_libjsig_version)();