mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-25 13:54:38 +02:00
8141529: Fix handling of _JAVA_SR_SIGNUM
Reviewed-by: dholmes, stuefe, dsamersoff
This commit is contained in:
parent
3904de571b
commit
0a4657e8c1
10 changed files with 97 additions and 98 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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*);
|
||||||
|
|
|
@ -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)();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue