Subject: [nathanw_sa] Fix one libpthread signal bug
To: None <tech-userlevel@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-userlevel
Date: 10/02/2002 13:12:31
--3MwIy2ne0vdjdPXF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
libpthread currently hard-codes __sigtramp_sigaction_1 in its sigaction
shim. This is wrong. It should use that libc uses. This patch fixes
that. Even though pthread-app signal delivery doesn't use the libc-provided
trampoline (libpthread provides its own), this avoids complications with
COMPAT_* kernel options being required to support various trampoline versions.
--
-- Jason R. Thorpe <thorpej@wasabisystems.com>
--3MwIy2ne0vdjdPXF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pthread-sig.patch"
Index: lib/libc/arch/alpha/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/alpha/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 __sigaction14_sigtramp.c
*** lib/libc/arch/alpha/sys/__sigaction14_sigtramp.c 2002/08/01 03:27:54 1.1.2.1
--- lib/libc/arch/alpha/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:35
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
Index: lib/libc/arch/arm/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/arm/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 __sigaction14_sigtramp.c
*** lib/libc/arch/arm/sys/__sigaction14_sigtramp.c 2002/08/01 03:27:55 1.1.2.1
--- lib/libc/arch/arm/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:35
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
Index: lib/libc/arch/i386/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/i386/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 __sigaction14_sigtramp.c
*** lib/libc/arch/i386/sys/__sigaction14_sigtramp.c 2002/08/01 03:27:56 1.1.2.1
--- lib/libc/arch/i386/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:35
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
Index: lib/libc/arch/m68k/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/m68k/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 __sigaction14_sigtramp.c
*** lib/libc/arch/m68k/sys/__sigaction14_sigtramp.c 2002/08/01 03:27:57 1.1.2.1
--- lib/libc/arch/m68k/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:36
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
Index: lib/libc/arch/mips/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/mips/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 __sigaction14_sigtramp.c
*** lib/libc/arch/mips/sys/__sigaction14_sigtramp.c 2002/08/01 03:27:58 1.1.2.1
--- lib/libc/arch/mips/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:36
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
Index: lib/libc/arch/ns32k/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/ns32k/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 __sigaction14_sigtramp.c
*** lib/libc/arch/ns32k/sys/__sigaction14_sigtramp.c 2002/08/01 03:27:59 1.1.2.1
--- lib/libc/arch/ns32k/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:36
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
Index: lib/libc/arch/powerpc/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/powerpc/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 __sigaction14_sigtramp.c
*** lib/libc/arch/powerpc/sys/__sigaction14_sigtramp.c 2002/08/01 03:28:02 1.1.2.1
--- lib/libc/arch/powerpc/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:37
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
Index: lib/libc/arch/sh3/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/sh3/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 __sigaction14_sigtramp.c
*** lib/libc/arch/sh3/sys/__sigaction14_sigtramp.c 2002/08/01 03:28:05 1.1.2.1
--- lib/libc/arch/sh3/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:37
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
Index: lib/libc/arch/sparc/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/sparc/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 __sigaction14_sigtramp.c
*** lib/libc/arch/sparc/sys/__sigaction14_sigtramp.c 2002/08/01 03:28:06 1.1.2.1
--- lib/libc/arch/sparc/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:37
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
Index: lib/libc/arch/sparc64/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/sparc64/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 __sigaction14_sigtramp.c
*** lib/libc/arch/sparc64/sys/__sigaction14_sigtramp.c 2002/08/01 03:28:06 1.1.2.1
--- lib/libc/arch/sparc64/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:37
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_1[];
Index: lib/libc/arch/vax/sys/__sigaction14_sigtramp.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/arch/vax/sys/__sigaction14_sigtramp.c,v
retrieving revision 1.1.2.2
diff -c -r1.1.2.2 __sigaction14_sigtramp.c
*** lib/libc/arch/vax/sys/__sigaction14_sigtramp.c 2002/09/17 21:32:47 1.1.2.2
--- lib/libc/arch/vax/sys/__sigaction14_sigtramp.c 2002/10/02 20:04:38
***************
*** 43,50 ****
#include "extern.h"
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_2[];
--- 43,52 ----
#include "extern.h"
+ __weak_alias(__sigaction14, __libc_sigaction14)
+
int
! __libc_sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
extern int __sigtramp_sigcontext_2[];
Index: include/signal.h
===================================================================
RCS file: /cvsroot/basesrc/include/signal.h,v
retrieving revision 1.21
diff -c -r1.21 signal.h
*** include/signal.h 2000/12/18 21:21:26 1.21
--- include/signal.h 2002/10/02 20:04:38
***************
*** 66,71 ****
--- 66,73 ----
#ifdef __LIBC12_SOURCE__
int sigaction __P((int, const struct sigaction13 *, struct sigaction13 *));
int __sigaction14 __P((int, const struct sigaction *, struct sigaction *));
+ int __libc_sigaction14 __P((int, const struct sigaction *,
+ struct sigaction *));
int sigaddset __P((sigset13_t *, int));
int __sigaddset14 __P((sigset_t *, int));
int sigdelset __P((sigset13_t *, int));
Index: lib/libpthread/TODO
===================================================================
RCS file: /cvsroot/basesrc/lib/libpthread/Attic/TODO,v
retrieving revision 1.1.2.13
diff -c -r1.1.2.13 TODO
*** lib/libpthread/TODO 2002/10/02 19:01:39 1.1.2.13
--- lib/libpthread/TODO 2002/10/02 20:04:38
***************
*** 7,17 ****
pthread_cond_broadcast() or pthread_exit() about removing an item
from the sleep queue. The locking protocols there need a little
adjustment.
- - pthread_sig.c: sigaction() currently hard-codes __sigtramp_sigcontext_1:
- this is incorrect. Instead of calling __sigaction_sigtramp() directly,
- libc should export a __libc_sigaction14() which sigaction() can call.
- Also, pthread_sig.c should probably be built with __LIBC12_SOURCE__ so
- that the signal version of sigaction(), et al can be explicit.
- pthread_sig.c: pthread__signal_tramp() is broken. It gets a ucontext,
but then hands off an empty (garbage from stack!) sigcontext to the
handler. The ucontext MUST be converted to a sigcontext, the handler
--- 7,12 ----
Index: lib/libpthread/pthread_sig.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libpthread/Attic/pthread_sig.c,v
retrieving revision 1.1.2.13
diff -c -r1.1.2.13 pthread_sig.c
*** lib/libpthread/pthread_sig.c 2002/08/02 22:19:48 1.1.2.13
--- lib/libpthread/pthread_sig.c 2002/10/02 20:04:39
***************
*** 36,41 ****
--- 36,44 ----
* POSSIBILITY OF SUCH DAMAGE.
*/
+ /* We're interposing a specific version of the signal interface. */
+ #define __LIBC12_SOURCE__
+
#include <assert.h>
#include <errno.h>
#include <lwp.h>
***************
*** 84,90 ****
pthread__signal_init(void)
{
SDPRINTF(("(signal_init) setting process sigmask\n"));
! sigprocmask(0, NULL, &pt_process_sigmask);
}
int
--- 87,93 ----
pthread__signal_init(void)
{
SDPRINTF(("(signal_init) setting process sigmask\n"));
! __sigprocmask14(0, NULL, &pt_process_sigmask);
}
int
***************
*** 107,121 ****
*/
int
! sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
pthread_t self;
struct sigaction realact;
- int __sigaction_sigtramp __P((int, const struct sigaction *,
- struct sigaction *, void *, int));
- extern int __sigtramp_sigcontext_1[];
-
self = pthread__self();
if (act != NULL) {
/* Save the information for our internal dispatch. */
--- 110,120 ----
*/
int
! __sigaction14(int sig, const struct sigaction *act, struct sigaction *oact)
{
pthread_t self;
struct sigaction realact;
self = pthread__self();
if (act != NULL) {
/* Save the information for our internal dispatch. */
***************
*** 131,146 ****
* stream of signals to exhaust the supply of upcalls.
*/
realact = *act;
! sigemptyset(&realact.sa_mask);
act = &realact;
}
! return __sigaction_sigtramp(sig, act, oact,
! __sigtramp_sigcontext_1, 1);
}
int
! sigsuspend(const sigset_t *sigmask)
{
pthread_t self;
sigset_t oldmask;
--- 130,144 ----
* stream of signals to exhaust the supply of upcalls.
*/
realact = *act;
! __sigemptyset14(&realact.sa_mask);
act = &realact;
}
! return (__libc_sigaction14(sig, act, oact));
}
int
! __sigsuspend14(const sigset_t *sigmask)
{
pthread_t self;
sigset_t oldmask;
***************
*** 269,297 ****
SDPRINTF(("(pt_sigmask %p) Process mask was changed to %08x\n",
self, pt_process_sigmask.__bits[0]));
/* See if there are any signals to take */
! sigemptyset(&takelist);
while ((i = firstsig(&self->pt_siglist)) != 0) {
! if (!sigismember(&self->pt_sigmask, i)) {
! sigaddset(&takelist, i);
! sigdelset(&self->pt_siglist, i);
}
}
while ((i = firstsig(&pt_process_siglist)) != 0) {
! if (!sigismember(&self->pt_sigmask, i)) {
! sigaddset(&takelist, i);
! sigdelset(&pt_process_siglist, i);
}
}
procmaskset = 0;
while ((i = firstsig(&takelist)) != 0) {
! if (!sigismember(&self->pt_sigmask, i)) {
/* Take the signal */
act = &pt_sigacts[i];
oldmask = self->pt_sigmask;
__sigplusset(&self->pt_sigmask,
&act->sa_mask);
! sigaddset(&self->pt_sigmask, i);
pthread_spinunlock(self, &pt_process_siglock);
pthread_spinunlock(self, &self->pt_siglock);
SDPRINTF(("(pt_sigmask %p) taking unblocked signal %d\n", self, i));
--- 267,295 ----
SDPRINTF(("(pt_sigmask %p) Process mask was changed to %08x\n",
self, pt_process_sigmask.__bits[0]));
/* See if there are any signals to take */
! __sigemptyset14(&takelist);
while ((i = firstsig(&self->pt_siglist)) != 0) {
! if (!__sigismember14(&self->pt_sigmask, i)) {
! __sigaddset14(&takelist, i);
! __sigdelset14(&self->pt_siglist, i);
}
}
while ((i = firstsig(&pt_process_siglist)) != 0) {
! if (!__sigismember14(&self->pt_sigmask, i)) {
! __sigaddset14(&takelist, i);
! __sigdelset14(&pt_process_siglist, i);
}
}
procmaskset = 0;
while ((i = firstsig(&takelist)) != 0) {
! if (!__sigismember14(&self->pt_sigmask, i)) {
/* Take the signal */
act = &pt_sigacts[i];
oldmask = self->pt_sigmask;
__sigplusset(&self->pt_sigmask,
&act->sa_mask);
! __sigaddset14(&self->pt_sigmask, i);
pthread_spinunlock(self, &pt_process_siglock);
pthread_spinunlock(self, &self->pt_siglock);
SDPRINTF(("(pt_sigmask %p) taking unblocked signal %d\n", self, i));
***************
*** 301,307 ****
handler(i, 0, &xxxsc);
pthread_spinlock(self, &self->pt_siglock);
pthread_spinlock(self, &pt_process_siglock);
! sigdelset(&takelist, i);
/* Reset masks */
self->pt_sigmask = oldmask;
tmp = pt_process_sigmask;
--- 299,305 ----
handler(i, 0, &xxxsc);
pthread_spinlock(self, &self->pt_siglock);
pthread_spinlock(self, &pt_process_siglock);
! __sigdelset14(&takelist, i);
/* Reset masks */
self->pt_sigmask = oldmask;
tmp = pt_process_sigmask;
***************
*** 309,315 ****
if (!__sigsetequal(&tmp, &pt_process_sigmask)){
pt_process_sigmask = tmp;
SDPRINTF(("(pt_sigmask %p) setting proc sigmask to %08x\n", pt_process_sigmask.__bits[0]));
! sigprocmask(SIG_SETMASK,
&pt_process_sigmask, NULL);
procmaskset = 1;
}
--- 307,313 ----
if (!__sigsetequal(&tmp, &pt_process_sigmask)){
pt_process_sigmask = tmp;
SDPRINTF(("(pt_sigmask %p) setting proc sigmask to %08x\n", pt_process_sigmask.__bits[0]));
! __sigprocmask14(SIG_SETMASK,
&pt_process_sigmask, NULL);
procmaskset = 1;
}
***************
*** 317,323 ****
}
if (!procmaskset) {
SDPRINTF(("(pt_sigmask %p) setting proc sigmask to %08x\n", self, pt_process_sigmask.__bits[0]));
! sigprocmask(SIG_SETMASK, &pt_process_sigmask, NULL);
}
}
pthread_spinunlock(self, &pt_process_siglock);
--- 315,321 ----
}
if (!procmaskset) {
SDPRINTF(("(pt_sigmask %p) setting proc sigmask to %08x\n", self, pt_process_sigmask.__bits[0]));
! __sigprocmask14(SIG_SETMASK, &pt_process_sigmask, NULL);
}
}
pthread_spinunlock(self, &pt_process_siglock);
***************
*** 375,381 ****
SDPRINTF((
"(pt_signal %p) target %p: state %d, mask %08x\n",
self, target, target->pt_state, target->pt_sigmask.__bits[0]));
! if (!sigismember(&target->pt_sigmask, sig)) {
if (target->pt_state != PT_STATE_BLOCKED_SYS) {
good = target;
/* Leave target locked */
--- 373,379 ----
SDPRINTF((
"(pt_signal %p) target %p: state %d, mask %08x\n",
self, target, target->pt_state, target->pt_sigmask.__bits[0]));
! if (!__sigismember14(&target->pt_sigmask, sig)) {
if (target->pt_state != PT_STATE_BLOCKED_SYS) {
good = target;
/* Leave target locked */
***************
*** 404,414 ****
* for later unblocking.
*/
pthread_spinlock(self, &pt_process_siglock);
! sigaddset(&pt_process_sigmask, sig);
SDPRINTF(("(pt_signal %p) lazily setting proc sigmask to "
"%08x\n", self, pt_process_sigmask.__bits[0]));
! sigprocmask(SIG_SETMASK, &pt_process_sigmask, NULL);
! sigaddset(&pt_process_siglist, sig);
pthread_spinunlock(self, &pt_process_siglock);
return;
}
--- 402,412 ----
* for later unblocking.
*/
pthread_spinlock(self, &pt_process_siglock);
! __sigaddset14(&pt_process_sigmask, sig);
SDPRINTF(("(pt_signal %p) lazily setting proc sigmask to "
"%08x\n", self, pt_process_sigmask.__bits[0]));
! __sigprocmask14(SIG_SETMASK, &pt_process_sigmask, NULL);
! __sigaddset14(&pt_process_siglist, sig);
pthread_spinunlock(self, &pt_process_siglock);
return;
}
***************
*** 429,444 ****
pthread_spinlock(self, &pt_process_siglock);
SDPRINTF(("(pt_signal %p) setting proc sigmask to "
"%08x\n", self, pt_process_sigmask.__bits[0]));
! sigprocmask(SIG_SETMASK, &pt_process_sigmask, NULL);
pthread_spinunlock(self, &pt_process_siglock);
! if (t && sigismember(&target->pt_sigmask, sig)) {
/* Record the signal for later delivery. */
! sigaddset(&target->pt_siglist, sig);
pthread_spinunlock(self, &target->pt_siglock);
return;
}
!
/*
* Ensure the victim is not running.
* In a MP world, it could be on another processor somewhere.
--- 427,442 ----
pthread_spinlock(self, &pt_process_siglock);
SDPRINTF(("(pt_signal %p) setting proc sigmask to "
"%08x\n", self, pt_process_sigmask.__bits[0]));
! __sigprocmask14(SIG_SETMASK, &pt_process_sigmask, NULL);
pthread_spinunlock(self, &pt_process_siglock);
! if (t && __sigismember14(&target->pt_sigmask, sig)) {
/* Record the signal for later delivery. */
! __sigaddset14(&target->pt_siglist, sig);
pthread_spinunlock(self, &target->pt_siglock);
return;
}
!
/*
* Ensure the victim is not running.
* In a MP world, it could be on another processor somewhere.
***************
*** 453,459 ****
*/
oldmask = target->pt_sigmask;
__sigplusset(&target->pt_sigmask, &pt_sigacts[sig].sa_mask);
! sigaddset(&target->pt_sigmask, sig);
pthread_spinunlock(self, &target->pt_siglock);
/*
--- 451,457 ----
*/
oldmask = target->pt_sigmask;
__sigplusset(&target->pt_sigmask, &pt_sigacts[sig].sa_mask);
! __sigaddset14(&target->pt_sigmask, sig);
pthread_spinunlock(self, &target->pt_siglock);
/*
--3MwIy2ne0vdjdPXF--