From 18955a72ddf9190f9850cb6b143fd39ff8ab6168 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Sun, 31 Jan 2016 15:11:15 +0100 Subject: hipe_x86_signal: cleanups - remove glibc < 2.3 code - move glibc-2.2 comment to glibc >= 2.3 block - remove obsolete "only supports" comment - remove support for broken sigaltstack() in pre-2.4 Linux kernels --- erts/emulator/hipe/hipe_x86_signal.c | 80 +++--------------------------------- 1 file changed, 6 insertions(+), 74 deletions(-) (limited to 'erts') diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c index b7dae88417..6887bdacbc 100644 --- a/erts/emulator/hipe/hipe_x86_signal.c +++ b/erts/emulator/hipe/hipe_x86_signal.c @@ -38,9 +38,6 @@ * * Our solution is to override the C library's signal handler setup * procedure with our own which enforces the SA_ONSTACK flag. - * - * XXX: This code only supports Linux with glibc-2.1 or above, - * and Solaris 8. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -55,27 +52,6 @@ #include "hipe_signal.h" #if __GLIBC__ == 2 && (__GLIBC_MINOR__ >= 3) -/* See comment below for glibc 2.2. */ -#ifndef __USE_GNU -#define __USE_GNU /* to un-hide RTLD_NEXT */ -#endif -#include -static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); -#define init_done() (__next_sigaction != 0) -extern int __sigaction(int, const struct sigaction*, struct sigaction*); -#define __SIGACTION __sigaction -static void do_init(void) -{ - __next_sigaction = dlsym(RTLD_NEXT, "__sigaction"); - if (__next_sigaction != 0) - return; - perror("dlsym"); - abort(); -} -#define INIT() do { if (!init_done()) do_init(); } while (0) -#endif /* glibc 2.3 */ - -#if __GLIBC__ == 2 && (__GLIBC_MINOR__ == 2 /*|| __GLIBC_MINOR__ == 3*/) /* * __libc_sigaction() is the core routine. * Without libpthread, sigaction() and __sigaction() are both aliases @@ -100,16 +76,14 @@ static void do_init(void) * old BSD or SysV interfaces. * glibc's internal calls to __sigaction() appear to be mostly safe. * hipe_signal_init() fixes some unsafe ones, e.g. the SIGPROF handler. - * - * Tested with glibc-2.1.92 on RedHat 7.0, glibc-2.2.2 on RedHat 7.1, - * glibc-2.2.4 on RedHat 7.2, and glibc-2.2.5 on RedHat 7.3. */ -#if 0 -/* works with 2.2.5 and 2.2.4, but not 2.2.2 or 2.1.92 */ +#ifndef __USE_GNU #define __USE_GNU /* to un-hide RTLD_NEXT */ +#endif #include static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); #define init_done() (__next_sigaction != 0) +extern int __sigaction(int, const struct sigaction*, struct sigaction*); #define __SIGACTION __sigaction static void do_init(void) { @@ -120,45 +94,7 @@ static void do_init(void) abort(); } #define INIT() do { if (!init_done()) do_init(); } while (0) -#else -/* semi-works with all 2.2 versions so far */ -extern int __sigaction(int, const struct sigaction*, struct sigaction*); -#define __next_sigaction __sigaction /* pthreads-aware version */ -#undef __SIGACTION /* we can't override __sigaction() */ -#define INIT() do{}while(0) -#endif -#endif /* glibc 2.2 */ - -#if __GLIBC__ == 2 && __GLIBC_MINOR__ == 1 -/* - * __sigaction() is the core routine. - * Without libpthread, sigaction() is an alias for __sigaction(). - * libpthread redefines sigaction() as a non-trivial wrapper around - * __sigaction(). - * glibc has internal calls to both sigaction() and __sigaction(). - * - * Overriding __sigaction() would be ideal, but doing so breaks - * libpthread (threads hang). Instead we override sigaction() and - * use dlsym RTLD_NEXT to find glibc's version of sigaction(). - * glibc's internal calls to __sigaction() appear to be mostly safe. - * hipe_signal_init() fixes some unsafe ones, e.g. the SIGPROF handler. - * - * Tested with glibc-2.1.3 on RedHat 6.2. - */ -#include -static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); -#define init_done() (__next_sigaction != 0) -#undef __SIGACTION -static void do_init(void) -{ - __next_sigaction = dlsym(RTLD_NEXT, "sigaction"); - if (__next_sigaction != 0) - return; - perror("dlsym"); - abort(); -} -#define INIT() do { if (!init_done()) do_init(); } while (0) -#endif /* glibc 2.1 */ +#endif /* glibc >= 2.3 */ /* Is there no standard identifier for Darwin/MacOSX ? */ #if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__) @@ -339,12 +275,8 @@ static void hipe_sigaltstack(void *ss_sp) ss.ss_flags = SS_ONSTACK; ss.ss_size = SIGSTKSZ; if (sigaltstack(&ss, NULL) < 0) { - /* might be a broken pre-2.4 Linux kernel, try harder */ - ss.ss_flags = 0; - if (sigaltstack(&ss, NULL) < 0) { - perror("sigaltstack"); - abort(); - } + perror("sigaltstack"); + abort(); } } -- cgit v1.2.3 From 050480b2326ea3583231a0de02fb087bf51db82a Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Sun, 31 Jan 2016 15:13:21 +0100 Subject: hipe_x86_signal: cleanups - add block for NetBSD, define dummy INIT() macro - eliminate ifndef NetBSD around INIT() invocation --- erts/emulator/hipe/hipe_x86_signal.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'erts') diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c index 6887bdacbc..741f570c50 100644 --- a/erts/emulator/hipe/hipe_x86_signal.c +++ b/erts/emulator/hipe/hipe_x86_signal.c @@ -192,6 +192,15 @@ static void do_init(void) #define INIT() do { if (!init_done()) do_init(); } while (0) #endif /* __FreeBSD__ */ +#if defined(__NetBSD__) +/* + * Note: This is only stub code to allow the build to succeed. + * Whether this actually provides the needed overrides for safe + * signal delivery or not is unknown. + */ +#define INIT() do { } while (0) +#endif /* __NetBSD__ */ + #if !(defined(__GLIBC__) || defined(__DARWIN__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__sun__)) /* * Unknown libc -- assume musl. Note: musl deliberately does not provide a musl-specific @@ -243,6 +252,7 @@ static int my_sigaction(int signum, const struct sigaction *act, struct sigactio return __next_sigaction(signum, act, oldact); } #endif + /* * This overrides the C library's core sigaction() procedure, catching * all its internal calls. @@ -313,9 +323,7 @@ void hipe_signal_init(void) struct sigaction sa; int i; -#ifndef __NetBSD__ INIT(); -#endif hipe_sigaltstack_init(); -- cgit v1.2.3 From 97ea79864fc9d55fa3679597d4c2dbe8e518e06a Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Sun, 31 Jan 2016 15:14:09 +0100 Subject: hipe_x86_signal: cleanups - rename __SIGACTION to LIBC_SIGACTION, to avoid defining _-prefixed symbols --- erts/emulator/hipe/hipe_x86_signal.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'erts') diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c index 741f570c50..6bb442490e 100644 --- a/erts/emulator/hipe/hipe_x86_signal.c +++ b/erts/emulator/hipe/hipe_x86_signal.c @@ -84,7 +84,7 @@ static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); #define init_done() (__next_sigaction != 0) extern int __sigaction(int, const struct sigaction*, struct sigaction*); -#define __SIGACTION __sigaction +#define LIBC_SIGACTION __sigaction static void do_init(void) { __next_sigaction = dlsym(RTLD_NEXT, "__sigaction"); @@ -121,7 +121,7 @@ static void do_init(void) static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); #define init_done() (__next_sigaction != 0) extern int _sigaction(int, const struct sigaction*, struct sigaction*); -#define __SIGACTION _sigaction +#define LIBC_SIGACTION _sigaction static void do_init(void) { __next_sigaction = dlsym(RTLD_NEXT, "sigaction"); @@ -157,7 +157,7 @@ static void do_init(void) #include static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); #define init_done() (__next_sigaction != 0) -#define __SIGACTION _sigaction +#define LIBC_SIGACTION _sigaction static void do_init(void) { __next_sigaction = dlsym(RTLD_NEXT, "_sigaction"); @@ -179,7 +179,7 @@ static void do_init(void) static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); #define init_done() (__next_sigaction != 0) extern int _sigaction(int, const struct sigaction*, struct sigaction*); -#define __SIGACTION _sigaction +#define LIBC_SIGACTION _sigaction static void do_init(void) { __next_sigaction = dlsym(RTLD_NEXT, "sigaction"); @@ -213,7 +213,7 @@ static void do_init(void) #include static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); #define init_done() (__next_sigaction != 0) -#define __SIGACTION __libc_sigaction +#define LIBC_SIGACTION __libc_sigaction static void do_init(void) { __next_sigaction = dlsym(RTLD_NEXT, "__libc_sigaction"); @@ -257,8 +257,8 @@ static int my_sigaction(int signum, const struct sigaction *act, struct sigactio * This overrides the C library's core sigaction() procedure, catching * all its internal calls. */ -#ifdef __SIGACTION -int __SIGACTION(int signum, const struct sigaction *act, struct sigaction *oldact) +#if defined(LIBC_SIGACTION) +int LIBC_SIGACTION(int signum, const struct sigaction *act, struct sigaction *oldact) { return my_sigaction(signum, act, oldact); } -- cgit v1.2.3 From 202c3dac37587e468b4c968a392c0b97668dda7e Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Sun, 31 Jan 2016 15:15:00 +0100 Subject: hipe_x86_signal: cleanups - rename __next_sigaction to next_sigaction, to avoid defining _-prefixed symbols - factor out common code for declaring and initializing next_sigaction, system-specific code now only needs to #define NEXT_SIGACTION --- erts/emulator/hipe/hipe_x86_signal.c | 89 +++++++++++------------------------- 1 file changed, 27 insertions(+), 62 deletions(-) (limited to 'erts') diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c index 6bb442490e..2e7e64eae3 100644 --- a/erts/emulator/hipe/hipe_x86_signal.c +++ b/erts/emulator/hipe/hipe_x86_signal.c @@ -80,20 +80,9 @@ #ifndef __USE_GNU #define __USE_GNU /* to un-hide RTLD_NEXT */ #endif -#include -static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); -#define init_done() (__next_sigaction != 0) +#define NEXT_SIGACTION "__sigaction" extern int __sigaction(int, const struct sigaction*, struct sigaction*); #define LIBC_SIGACTION __sigaction -static void do_init(void) -{ - __next_sigaction = dlsym(RTLD_NEXT, "__sigaction"); - if (__next_sigaction != 0) - return; - perror("dlsym"); - abort(); -} -#define INIT() do { if (!init_done()) do_init(); } while (0) #endif /* glibc >= 2.3 */ /* Is there no standard identifier for Darwin/MacOSX ? */ @@ -117,21 +106,10 @@ static void do_init(void) * The other _sigaction, _sigaction_no_bind I don't understand the purpose * of and don't modify. */ -#include -static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); -#define init_done() (__next_sigaction != 0) +#define NEXT_SIGACTION "sigaction" extern int _sigaction(int, const struct sigaction*, struct sigaction*); #define LIBC_SIGACTION _sigaction -static void do_init(void) -{ - __next_sigaction = dlsym(RTLD_NEXT, "sigaction"); - if (__next_sigaction != 0) - return; - perror("dlsym_darwin"); - abort(); -} #define _NSIG NSIG -#define INIT() do { if (!init_done()) do_init(); } while (0) #endif /* __DARWIN__ */ #if defined(__sun__) @@ -154,20 +132,9 @@ static void do_init(void) * our init routine has had a chance to find _sigaction()'s address. * This forces us to initialise at the first call. */ -#include -static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); -#define init_done() (__next_sigaction != 0) +#define NEXT_SIGACTION "_sigaction" #define LIBC_SIGACTION _sigaction -static void do_init(void) -{ - __next_sigaction = dlsym(RTLD_NEXT, "_sigaction"); - if (__next_sigaction != 0) - return; - perror("dlsym"); - abort(); -} #define _NSIG NSIG -#define INIT() do { if (!init_done()) do_init(); } while (0) #endif /* __sun__ */ #if defined(__FreeBSD__) @@ -175,21 +142,10 @@ static void do_init(void) * This is a copy of Darwin code for FreeBSD. * CAVEAT: detailed semantics are not verified yet. */ -#include -static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); -#define init_done() (__next_sigaction != 0) +#define NEXT_SIGACTION "sigaction" extern int _sigaction(int, const struct sigaction*, struct sigaction*); #define LIBC_SIGACTION _sigaction -static void do_init(void) -{ - __next_sigaction = dlsym(RTLD_NEXT, "sigaction"); - if (__next_sigaction != 0) - return; - perror("dlsym_freebsd"); - abort(); -} #define _NSIG NSIG -#define INIT() do { if (!init_done()) do_init(); } while (0) #endif /* __FreeBSD__ */ #if defined(__NetBSD__) @@ -198,7 +154,7 @@ static void do_init(void) * Whether this actually provides the needed overrides for safe * signal delivery or not is unknown. */ -#define INIT() do { } while (0) +#undef NEXT_SIGACTION #endif /* __NetBSD__ */ #if !(defined(__GLIBC__) || defined(__DARWIN__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__sun__)) @@ -210,30 +166,39 @@ static void do_init(void) * There are libc-internal calls to __libc_sigaction which install handlers, so we must * override __libc_sigaction rather than __sigaction. */ -#include -static int (*__next_sigaction)(int, const struct sigaction*, struct sigaction*); -#define init_done() (__next_sigaction != 0) +#define NEXT_SIGACTION "__libc_sigaction" #define LIBC_SIGACTION __libc_sigaction +#ifndef _NSIG +#define _NSIG NSIG +#endif +#endif /* !(__GLIBC__ || __DARWIN__ || __NetBSD__ || __FreeBSD__ || __sun__) */ + +#if defined(NEXT_SIGACTION) +/* + * Initialize a function pointer to the libc core sigaction routine, + * to be used by our wrappers. + */ +#include +static int (*next_sigaction)(int, const struct sigaction*, struct sigaction*); static void do_init(void) { - __next_sigaction = dlsym(RTLD_NEXT, "__libc_sigaction"); - if (__next_sigaction != 0) + next_sigaction = dlsym(RTLD_NEXT, NEXT_SIGACTION); + if (next_sigaction != 0) return; perror("dlsym"); abort(); } -#ifndef _NSIG -#define _NSIG NSIG -#endif -#define INIT() do { if (!init_done()) do_init(); } while (0) -#endif /* !(__GLIBC__ || __DARWIN__ || __NetBSD__ || __FreeBSD__ || __sun__) */ +#define INIT() do { if (!next_sigaction) do_init(); } while (0) +#else /* !defined(NEXT_SIGACTION) */ +#define INIT() do { } while (0) +#endif /* !defined(NEXT_SIGACTION) */ -#if !defined(__NetBSD__) +#if defined(NEXT_SIGACTION) /* * This is our wrapper for sigaction(). sigaction() can be called before * hipe_signal_init() has been executed, especially when threads support * has been linked with the executable. Therefore, we must initialise - * __next_sigaction() dynamically, the first time it's needed. + * next_sigaction() dynamically, the first time it's needed. */ static int my_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) { @@ -249,7 +214,7 @@ static int my_sigaction(int signum, const struct sigaction *act, struct sigactio newact.sa_flags |= SA_ONSTACK; act = &newact; } - return __next_sigaction(signum, act, oldact); + return next_sigaction(signum, act, oldact); } #endif -- cgit v1.2.3 From 2d86df7cf1c5645fa80ef091b1f9a39ce44f764d Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Sun, 31 Jan 2016 15:15:40 +0100 Subject: hipe_x86_signal: cleanups - move extern declarations of LIBC_SIGACTION() from system-specific blocks to the common LIBC_SIGACTION block --- erts/emulator/hipe/hipe_x86_signal.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'erts') diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c index 2e7e64eae3..b44899401b 100644 --- a/erts/emulator/hipe/hipe_x86_signal.c +++ b/erts/emulator/hipe/hipe_x86_signal.c @@ -81,7 +81,6 @@ #define __USE_GNU /* to un-hide RTLD_NEXT */ #endif #define NEXT_SIGACTION "__sigaction" -extern int __sigaction(int, const struct sigaction*, struct sigaction*); #define LIBC_SIGACTION __sigaction #endif /* glibc >= 2.3 */ @@ -107,7 +106,6 @@ extern int __sigaction(int, const struct sigaction*, struct sigaction*); * of and don't modify. */ #define NEXT_SIGACTION "sigaction" -extern int _sigaction(int, const struct sigaction*, struct sigaction*); #define LIBC_SIGACTION _sigaction #define _NSIG NSIG #endif /* __DARWIN__ */ @@ -143,7 +141,6 @@ extern int _sigaction(int, const struct sigaction*, struct sigaction*); * CAVEAT: detailed semantics are not verified yet. */ #define NEXT_SIGACTION "sigaction" -extern int _sigaction(int, const struct sigaction*, struct sigaction*); #define LIBC_SIGACTION _sigaction #define _NSIG NSIG #endif /* __FreeBSD__ */ @@ -218,11 +215,12 @@ static int my_sigaction(int signum, const struct sigaction *act, struct sigactio } #endif +#if defined(LIBC_SIGACTION) /* * This overrides the C library's core sigaction() procedure, catching * all its internal calls. */ -#if defined(LIBC_SIGACTION) +extern int LIBC_SIGACTION(int, const struct sigaction*, struct sigaction*); int LIBC_SIGACTION(int signum, const struct sigaction *act, struct sigaction *oldact) { return my_sigaction(signum, act, oldact); -- cgit v1.2.3 From 6823fb17e3cd9429f9e562d3e2e096bc1bb3ebe7 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Sun, 31 Jan 2016 15:16:31 +0100 Subject: hipe_x86_signal: cleanups - replace system-specific #ifndef around sigaction() override with a test for OVERRIDE_SIGACTION, #define or #undef that as appropriate in each system-specific block --- erts/emulator/hipe/hipe_x86_signal.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'erts') diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c index b44899401b..10a40ce901 100644 --- a/erts/emulator/hipe/hipe_x86_signal.c +++ b/erts/emulator/hipe/hipe_x86_signal.c @@ -82,6 +82,7 @@ #endif #define NEXT_SIGACTION "__sigaction" #define LIBC_SIGACTION __sigaction +#define OVERRIDE_SIGACTION #endif /* glibc >= 2.3 */ /* Is there no standard identifier for Darwin/MacOSX ? */ @@ -107,6 +108,7 @@ */ #define NEXT_SIGACTION "sigaction" #define LIBC_SIGACTION _sigaction +#undef OVERRIDE_SIGACTION #define _NSIG NSIG #endif /* __DARWIN__ */ @@ -132,6 +134,7 @@ */ #define NEXT_SIGACTION "_sigaction" #define LIBC_SIGACTION _sigaction +#define OVERRIDE_SIGACTION #define _NSIG NSIG #endif /* __sun__ */ @@ -142,6 +145,7 @@ */ #define NEXT_SIGACTION "sigaction" #define LIBC_SIGACTION _sigaction +#undef OVERRIDE_SIGACTION #define _NSIG NSIG #endif /* __FreeBSD__ */ @@ -152,6 +156,7 @@ * signal delivery or not is unknown. */ #undef NEXT_SIGACTION +#undef OVERRIDE_SIGACTION #endif /* __NetBSD__ */ #if !(defined(__GLIBC__) || defined(__DARWIN__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__sun__)) @@ -165,6 +170,7 @@ */ #define NEXT_SIGACTION "__libc_sigaction" #define LIBC_SIGACTION __libc_sigaction +#define OVERRIDE_SIGACTION #ifndef _NSIG #define _NSIG NSIG #endif @@ -227,10 +233,10 @@ int LIBC_SIGACTION(int signum, const struct sigaction *act, struct sigaction *ol } #endif +#if defined(OVERRIDE_SIGACTION) /* * This catches the application's own sigaction() calls. */ -#if !defined(__DARWIN__) && !defined(__NetBSD__) && !defined(__FreeBSD__) int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) { return my_sigaction(signum, act, oldact); -- cgit v1.2.3 From 22ec76d8bc0e4dc0017791a7bd700b3d3565311a Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Tue, 9 Feb 2016 10:14:36 +0100 Subject: hipe_sigaltstack: correct initialization of ss.ss_flags SS_ONSTACK may be set in oss, but it's not supposed to be set in ss, and some systems correctly reject that; current Linux kernels accept but ignore it in ss --- erts/emulator/hipe/hipe_x86_signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'erts') diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c index 10a40ce901..0ecd13c4bc 100644 --- a/erts/emulator/hipe/hipe_x86_signal.c +++ b/erts/emulator/hipe/hipe_x86_signal.c @@ -251,7 +251,7 @@ static void hipe_sigaltstack(void *ss_sp) stack_t ss; ss.ss_sp = ss_sp; - ss.ss_flags = SS_ONSTACK; + ss.ss_flags = 0; ss.ss_size = SIGSTKSZ; if (sigaltstack(&ss, NULL) < 0) { perror("sigaltstack"); -- cgit v1.2.3