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 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 <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#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 bool jvm_signal_installed = false;
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 @@ static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
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 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
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 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
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 signal(int sig, sa_handler_t disp) {
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 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
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 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
*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 @@ 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() {
signal_lock();
sigemptyset(&jvmsigs);
jvm_signal_installing = true;
tid = pthread_self();
signal_unlock();
@ -226,7 +224,7 @@ void JVM_end_signal_setting() {
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;

View File

@ -2769,8 +2769,12 @@ static int SR_initialize() {
// 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 @@ void javaSignalHandler(int sig, siginfo_t* info, void* uc) {
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 @@ bool os::Aix::chained_handler(int sig, siginfo_t* siginfo, void* context) {
}
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 @@ void os::Aix::set_signal_handler(int sig, bool set_installed) {
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 @@ void os::Aix::install_signal_handlers() {
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);

View File

@ -34,15 +34,9 @@ static bool zero_page_read_protected() { return false; }
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 @@ class Aix {
static void check_signal_handler(int sig);
// For signal flags diagnostics
static int sigflags[MAXSIGNUM];
protected:
static julong _physical_memory;

View File

@ -36,12 +36,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#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 */

View File

@ -2831,8 +2831,12 @@ static int SR_initialize() {
// 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 @@ void signalHandler(int sig, siginfo_t* info, void* uc) {
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 @@ bool os::Bsd::chained_handler(int sig, siginfo_t* siginfo, void* context) {
}
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 @@ void os::Bsd::set_signal_handler(int sig, bool set_installed) {
#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);

View File

@ -40,10 +40,6 @@ class Bsd {
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 @@ class Bsd {
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;

View File

@ -35,16 +35,19 @@
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#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 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
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 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
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 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
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 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
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);

View File

@ -3989,15 +3989,19 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
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 @@ void signalHandler(int sig, siginfo_t* info, void* uc) {
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 @@ bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) {
}
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 @@ void os::Linux::set_signal_handler(int sig, bool set_installed) {
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);

View File

@ -34,11 +34,6 @@ class Linux {
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 @@ class Linux {
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*);

View File

@ -113,9 +113,6 @@ class Solaris {
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)();