8141529: Fix handling of _JAVA_SR_SIGNUM

Reviewed-by: dholmes, stuefe, dsamersoff
This commit is contained in:
Goetz Lindenmaier 2015-11-05 15:05:59 +01:00
parent 3904de571b
commit 0a4657e8c1
10 changed files with 97 additions and 98 deletions

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 2013 SAP AG. All rights reserved. * Copyright 2012, 2015 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,26 +36,23 @@
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#define bool int #define bool int
#define true 1 #define true 1
#define false 0 #define false 0
// Highest so far on AIX 5.2 is SIGSAK (63) static struct sigaction sact[NSIG]; /* saved signal handlers */
#define MAXSIGNUM 63 static sigset_t jvmsigs; /* Signals used by jvm. */
#define MASK(sig) ((unsigned int)1 << sig)
static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ /* Used to synchronize the installation of signal handlers. */
static unsigned int jvmsigs = 0; /* signals used by jvm */
/* used to synchronize the installation of signal handlers */
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static pthread_t tid = 0; static pthread_t tid = 0;
typedef void (*sa_handler_t)(int); typedef void (*sa_handler_t)(int);
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); 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 sa_handler_t (*signal_like_function_t)(int, sa_handler_t);
typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *); typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *);
@ -68,7 +65,7 @@ static bool jvm_signal_installed = false;
static void signal_lock() { static void signal_lock() {
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
/* When the jvm is installing its set of signal handlers, threads /* 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 (jvm_signal_installing) {
if (tid != pthread_self()) { if (tid != pthread_self()) {
pthread_cond_wait(&cond, &mutex); pthread_cond_wait(&cond, &mutex);
@ -84,10 +81,10 @@ static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
bool is_sigset) { bool is_sigset) {
if (os_signal == NULL) { if (os_signal == NULL) {
if (!is_sigset) { if (!is_sigset) {
// Aix: call functions directly instead of dlsym'ing them // Aix: call functions directly instead of dlsym'ing them.
os_signal = signal; os_signal = signal;
} else { } else {
// Aix: call functions directly instead of dlsym'ing them // Aix: call functions directly instead of dlsym'ing them.
os_signal = sigset; os_signal = sigset;
} }
if (os_signal == NULL) { if (os_signal == NULL) {
@ -112,7 +109,7 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
signal_lock(); signal_lock();
sigused = (MASK(sig) & jvmsigs) != 0; sigused = sigismember(&jvmsigs, sig);
if (jvm_signal_installed && sigused) { if (jvm_signal_installed && sigused) {
/* jvm has installed its signal handler for this signal. */ /* jvm has installed its signal handler for this signal. */
/* Save the handler. Don't really install it. */ /* Save the handler. Don't really install it. */
@ -129,7 +126,7 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
save_signal_handler(sig, oldhandler); save_signal_handler(sig, oldhandler);
/* Record the signals used by jvm */ /* Record the signals used by jvm */
jvmsigs |= MASK(sig); sigaddset(&jvmsigs, sig);
signal_unlock(); signal_unlock();
return oldhandler; return oldhandler;
@ -154,7 +151,7 @@ sa_handler_t sigset(int sig, sa_handler_t disp) {
static int call_os_sigaction(int sig, const struct sigaction *act, static int call_os_sigaction(int sig, const struct sigaction *act,
struct sigaction *oact) { struct sigaction *oact) {
if (os_sigaction == NULL) { 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; os_sigaction = sigaction;
if (os_sigaction == NULL) { if (os_sigaction == NULL) {
printf("%s\n", dlerror()); printf("%s\n", dlerror());
@ -171,7 +168,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
signal_lock(); signal_lock();
sigused = (MASK(sig) & jvmsigs) != 0; sigused = sigismember(&jvmsigs, sig);
if (jvm_signal_installed && sigused) { if (jvm_signal_installed && sigused) {
/* jvm has installed its signal handler for this signal. */ /* jvm has installed its signal handler for this signal. */
/* Save the handler. Don't really install it. */ /* Save the handler. Don't really install it. */
@ -193,8 +190,8 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
*oact = oldAct; *oact = oldAct;
} }
/* Record the signals used by jvm */ /* Record the signals used by jvm. */
jvmsigs |= MASK(sig); sigaddset(&jvmsigs, sig);
signal_unlock(); signal_unlock();
return res; return res;
@ -208,9 +205,10 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
} }
} }
/* The three functions for the jvm to call into */ /* The three functions for the jvm to call into. */
void JVM_begin_signal_setting() { void JVM_begin_signal_setting() {
signal_lock(); signal_lock();
sigemptyset(&jvmsigs);
jvm_signal_installing = true; jvm_signal_installing = true;
tid = pthread_self(); tid = pthread_self();
signal_unlock(); signal_unlock();
@ -226,7 +224,7 @@ void JVM_end_signal_setting() {
struct sigaction *JVM_get_signal_action(int sig) { struct sigaction *JVM_get_signal_action(int sig) {
/* Does race condition make sense here? */ /* Does race condition make sense here? */
if ((MASK(sig) & jvmsigs) != 0) { if (sigismember(&jvmsigs, sig)) {
return &sact[sig]; return &sact[sig];
} }
return NULL; return NULL;

View file

@ -2769,8 +2769,12 @@ static int SR_initialize() {
// Get signal number to use for suspend/resume // Get signal number to use for suspend/resume
if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
int sig = ::strtol(s, 0, 10); 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; 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 @@ void javaSignalHandler(int sig, siginfo_t* info, void* uc) {
bool os::Aix::signal_handlers_are_installed = false; bool os::Aix::signal_handlers_are_installed = false;
// For signal-chaining // For signal-chaining
struct sigaction os::Aix::sigact[MAXSIGNUM]; struct sigaction sigact[NSIG];
unsigned int os::Aix::sigs = 0; sigset_t sigs;
bool os::Aix::libjsig_is_loaded = false; bool os::Aix::libjsig_is_loaded = false;
typedef struct sigaction *(*get_signal_t)(int); typedef struct sigaction *(*get_signal_t)(int);
get_signal_t os::Aix::get_signal_action = NULL; get_signal_t os::Aix::get_signal_action = NULL;
@ -3045,30 +3049,32 @@ bool os::Aix::chained_handler(int sig, siginfo_t* siginfo, void* context) {
} }
struct sigaction* os::Aix::get_preinstalled_handler(int sig) { struct sigaction* os::Aix::get_preinstalled_handler(int sig) {
if ((((unsigned int)1 << sig) & sigs) != 0) { if (sigismember(&sigs, sig)) {
return &sigact[sig]; return &sigact[sig];
} }
return NULL; return NULL;
} }
void os::Aix::save_preinstalled_handler(int sig, struct sigaction& oldAct) { 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; sigact[sig] = oldAct;
sigs |= (unsigned int)1 << sig; sigaddset(&sigs, sig);
} }
// for diagnostic // for diagnostic
int os::Aix::sigflags[MAXSIGNUM]; int sigflags[NSIG];
int os::Aix::get_our_sigflags(int sig) { 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]; return sigflags[sig];
} }
void os::Aix::set_our_sigflags(int sig, int flags) { void os::Aix::set_our_sigflags(int sig, int flags) {
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
if (sig > 0 && sig < NSIG) {
sigflags[sig] = flags; sigflags[sig] = flags;
} }
}
void os::Aix::set_signal_handler(int sig, bool set_installed) { void os::Aix::set_signal_handler(int sig, bool set_installed) {
// Check for overwrite. // Check for overwrite.
@ -3107,7 +3113,7 @@ void os::Aix::set_signal_handler(int sig, bool set_installed) {
sigAct.sa_flags = SA_SIGINFO|SA_RESTART; sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
} }
// Save flags, which are set by ours // 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; sigflags[sig] = sigAct.sa_flags;
int ret = sigaction(sig, &sigAct, &oldAct); int ret = sigaction(sig, &sigAct, &oldAct);
@ -3140,10 +3146,11 @@ void os::Aix::install_signal_handlers() {
assert(UseSignalChaining, "should enable signal-chaining"); assert(UseSignalChaining, "should enable signal-chaining");
} }
if (libjsig_is_loaded) { if (libjsig_is_loaded) {
// Tell libjsig jvm is setting signal handlers // Tell libjsig jvm is setting signal handlers.
(*begin_signal_setting)(); (*begin_signal_setting)();
} }
::sigemptyset(&sigs);
set_signal_handler(SIGSEGV, true); set_signal_handler(SIGSEGV, true);
set_signal_handler(SIGPIPE, true); set_signal_handler(SIGPIPE, true);
set_signal_handler(SIGBUS, true); set_signal_handler(SIGBUS, true);

View file

@ -34,15 +34,9 @@ static bool zero_page_read_protected() { return false; }
class Aix { class Aix {
friend class os; 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. // Length of strings included in the libperfstat structures.
#define IDENTIFIER_LENGTH 64 #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(), static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
// __sigaction(), signal() is loaded // __sigaction(), signal() is loaded
static struct sigaction *(*get_signal_action)(int); static struct sigaction *(*get_signal_action)(int);
@ -51,9 +45,6 @@ class Aix {
static void check_signal_handler(int sig); static void check_signal_handler(int sig);
// For signal flags diagnostics
static int sigflags[MAXSIGNUM];
protected: protected:
static julong _physical_memory; static julong _physical_memory;

View file

@ -36,12 +36,14 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#define MAXSIGNUM 32 #define MASK(sig) ((uint32_t)1 << (sig-1)) // 0 is not a signal.
#define MASK(sig) ((unsigned int)1 << sig) #if (32 < NSIG-1)
#error "Not all signals can be encoded in jvmsigs. Adapt its type!"
static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ #endif
static unsigned int jvmsigs = 0; /* signals used by jvm */ 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) */ static __thread bool reentry = false; /* prevent reentry deadlock (per-thread) */
/* used to synchronize the installation of signal handlers */ /* used to synchronize the installation of signal handlers */

View file

@ -2831,8 +2831,12 @@ static int SR_initialize() {
// Get signal number to use for suspend/resume // Get signal number to use for suspend/resume
if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
int sig = ::strtol(s, 0, 10); 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; 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 @@ void signalHandler(int sig, siginfo_t* info, void* uc) {
bool os::Bsd::signal_handlers_are_installed = false; bool os::Bsd::signal_handlers_are_installed = false;
// For signal-chaining // For signal-chaining
struct sigaction os::Bsd::sigact[MAXSIGNUM]; struct sigaction sigact[NSIG];
unsigned int os::Bsd::sigs = 0; 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; bool os::Bsd::libjsig_is_loaded = false;
typedef struct sigaction *(*get_signal_t)(int); typedef struct sigaction *(*get_signal_t)(int);
get_signal_t os::Bsd::get_signal_action = NULL; get_signal_t os::Bsd::get_signal_action = NULL;
@ -3064,30 +3071,32 @@ bool os::Bsd::chained_handler(int sig, siginfo_t* siginfo, void* context) {
} }
struct sigaction* os::Bsd::get_preinstalled_handler(int sig) { 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 &sigact[sig];
} }
return NULL; return NULL;
} }
void os::Bsd::save_preinstalled_handler(int sig, struct sigaction& oldAct) { 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; sigact[sig] = oldAct;
sigs |= (unsigned int)1 << sig; sigs |= (uint32_t)1 << (sig-1);
} }
// for diagnostic // for diagnostic
int os::Bsd::sigflags[MAXSIGNUM]; int sigflags[NSIG];
int os::Bsd::get_our_sigflags(int sig) { 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]; return sigflags[sig];
} }
void os::Bsd::set_our_sigflags(int sig, int flags) { void os::Bsd::set_our_sigflags(int sig, int flags) {
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
if (sig > 0 && sig < NSIG) {
sigflags[sig] = flags; sigflags[sig] = flags;
} }
}
void os::Bsd::set_signal_handler(int sig, bool set_installed) { void os::Bsd::set_signal_handler(int sig, bool set_installed) {
// Check for overwrite. // Check for overwrite.
@ -3137,7 +3146,7 @@ void os::Bsd::set_signal_handler(int sig, bool set_installed) {
#endif #endif
// Save flags, which are set by ours // 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; sigflags[sig] = sigAct.sa_flags;
int ret = sigaction(sig, &sigAct, &oldAct); int ret = sigaction(sig, &sigAct, &oldAct);

View file

@ -40,10 +40,6 @@ class Bsd {
friend class os; friend class os;
// For signal-chaining // 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(), static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
// __sigaction(), signal() is loaded // __sigaction(), signal() is loaded
static struct sigaction *(*get_signal_action)(int); static struct sigaction *(*get_signal_action)(int);
@ -52,9 +48,6 @@ class Bsd {
static void check_signal_handler(int sig); static void check_signal_handler(int sig);
// For signal flags diagnostics
static int sigflags[MAXSIGNUM];
#ifdef __APPLE__ #ifdef __APPLE__
// mach_absolute_time // mach_absolute_time
static mach_timebase_info_data_t _timebase_info; static mach_timebase_info_data_t _timebase_info;

View file

@ -35,16 +35,19 @@
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#define bool int #define bool int
#define true 1 #define true 1
#define false 0 #define false 0
#define MAXSIGNUM 32 #define MASK(sig) ((uint64_t)1 << (sig-1)) // 0 is not a signal.
#define MASK(sig) ((unsigned int)1 << sig) // Check whether all signals fit into jvmsigs. -1 as MASK shifts by -1.
#if (64 < NSIG-1)
static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ #error "Not all signals can be encoded in jvmsigs. Adapt its type!"
static unsigned int jvmsigs = 0; /* signals used by jvm */ #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 */ /* used to synchronize the installation of signal handlers */
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
@ -107,7 +110,7 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
signal_lock(); signal_lock();
sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0); sigused = (sig < NSIG) && ((MASK(sig) & jvmsigs) != 0);
if (jvm_signal_installed && sigused) { if (jvm_signal_installed && sigused) {
/* jvm has installed its signal handler for this signal. */ /* jvm has installed its signal handler for this signal. */
/* Save the handler. Don't really install it. */ /* Save the handler. Don't really install it. */
@ -116,7 +119,7 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
signal_unlock(); signal_unlock();
return oldhandler; 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 /* jvm is installing its signal handlers. Install the new
* handlers and save the old ones. jvm uses sigaction(). * handlers and save the old ones. jvm uses sigaction().
* Leave the piece here just in case. */ * Leave the piece here just in case. */
@ -165,7 +168,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
signal_lock(); signal_lock();
sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0); sigused = (sig < NSIG) && ((MASK(sig) & jvmsigs) != 0);
if (jvm_signal_installed && sigused) { if (jvm_signal_installed && sigused) {
/* jvm has installed its signal handler for this signal. */ /* jvm has installed its signal handler for this signal. */
/* Save the handler. Don't really install it. */ /* Save the handler. Don't really install it. */
@ -178,7 +181,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
signal_unlock(); signal_unlock();
return 0; 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 /* jvm is installing its signal handlers. Install the new
* handlers and save the old ones. */ * handlers and save the old ones. */
res = call_os_sigaction(sig, act, &oldAct); res = call_os_sigaction(sig, act, &oldAct);

View file

@ -3989,15 +3989,19 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
errno = old_errno; errno = old_errno;
} }
static int SR_initialize() { static int SR_initialize() {
struct sigaction act; struct sigaction act;
char *s; char *s;
// Get signal number to use for suspend/resume // Get signal number to use for suspend/resume
if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
int sig = ::strtol(s, 0, 10); 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; 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 @@ void signalHandler(int sig, siginfo_t* info, void* uc) {
bool os::Linux::signal_handlers_are_installed = false; bool os::Linux::signal_handlers_are_installed = false;
// For signal-chaining // For signal-chaining
struct sigaction os::Linux::sigact[MAXSIGNUM]; struct sigaction sigact[NSIG];
unsigned int os::Linux::sigs = 0; 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; bool os::Linux::libjsig_is_loaded = false;
typedef struct sigaction *(*get_signal_t)(int); typedef struct sigaction *(*get_signal_t)(int);
get_signal_t os::Linux::get_signal_action = NULL; get_signal_t os::Linux::get_signal_action = NULL;
@ -4230,29 +4237,29 @@ bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) {
} }
struct sigaction* os::Linux::get_preinstalled_handler(int sig) { 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 &sigact[sig];
} }
return NULL; return NULL;
} }
void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) { 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; sigact[sig] = oldAct;
sigs |= (unsigned int)1 << sig; sigs |= (uint64_t)1 << (sig-1);
} }
// for diagnostic // for diagnostic
int os::Linux::sigflags[MAXSIGNUM]; int sigflags[NSIG];
int os::Linux::get_our_sigflags(int sig) { 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]; return sigflags[sig];
} }
void os::Linux::set_our_sigflags(int sig, int flags) { void os::Linux::set_our_sigflags(int sig, int flags) {
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
if (sig > 0 && sig < MAXSIGNUM) { if (sig > 0 && sig < NSIG) {
sigflags[sig] = flags; sigflags[sig] = flags;
} }
} }
@ -4292,7 +4299,7 @@ void os::Linux::set_signal_handler(int sig, bool set_installed) {
sigAct.sa_flags = SA_SIGINFO|SA_RESTART; sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
} }
// Save flags, which are set by ours // 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; sigflags[sig] = sigAct.sa_flags;
int ret = sigaction(sig, &sigAct, &oldAct); int ret = sigaction(sig, &sigAct, &oldAct);

View file

@ -34,11 +34,6 @@ class Linux {
friend class os; friend class os;
friend class TestReserveMemorySpecial; 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(), static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
// __sigaction(), signal() is loaded // __sigaction(), signal() is loaded
static struct sigaction *(*get_signal_action)(int); static struct sigaction *(*get_signal_action)(int);
@ -47,9 +42,6 @@ class Linux {
static void check_signal_handler(int sig); 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 (*_clock_gettime)(clockid_t, struct timespec *);
static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *); static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
static int (*_pthread_setname_np)(pthread_t, const char*); static int (*_pthread_setname_np)(pthread_t, const char*);

View file

@ -113,9 +113,6 @@ class Solaris {
static void try_enable_extended_io(); 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_signal_action)(int);
static struct sigaction *get_preinstalled_handler(int); static struct sigaction *get_preinstalled_handler(int);
static int (*get_libjsig_version)(); static int (*get_libjsig_version)();