Date: Wed, 31 Oct 2001 12:29:00 GMT From: Nicholas Barnes <nb@ravenbrook.com> To: FreeBSD-gnats-submit@freebsd.org Cc: mps-staff@ravenbrook.com Subject: bin/31661: pthread_kill signal handler doesn't get sigcontext or ucontext Message-ID: <200110311229.f9VCT0Q23978@thrush.ravenbrook.com>
next in thread | raw e-mail | index | archive | help
>Number: 31661 >Category: bin >Synopsis: pthread_kill signal handler doesn't get sigcontext or ucontext >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Oct 31 04:30:06 PST 2001 >Closed-Date: >Last-Modified: >Originator: Nicholas Barnes >Release: FreeBSD 4.4-STABLE i386 >Organization: Ravenbrook Limited >Environment: System: FreeBSD thrush.ravenbrook.com 4.4-STABLE FreeBSD 4.4-STABLE #2: Mon Oct 15 10:12:14 BST 2001 nb@thrush.ravenbrook.com:/usr/obj/usr/src/sys/THRUSH-2001-04-17 i386 cvsup/buildworld/installworld on 2001-10-15. >Description: The signal handler for a signal caused by pthread_kill only receives a single useful argument: the signal. Man sigaction says it should get either code + sigcontext or info + ucontext (depending on whether SA_SIGINFO is set). But in fact these subsequent arguments always get 0 (or NULL). This means that I can't use pthread_kill to suspend a thread and get its context; required for some kinds of garbage collection. >How-To-Repeat: /* Test program to show that per-thread signals are not delivered with * useful code, sigcontext, siginfo, or ucontext. * FreeBSD 4.4-STABLE, 2001-10-31. * Nick Barnes, 2001-10-31. */ #include <pthread.h> #include <signal.h> #include <stdio.h> #include <unistd.h> /* variables to record the arguments passed to signal handlers */ static int ANSIHandled = 0; static int ANSISignal = 0; static pthread_t ANSIPthread = NULL; static int BSDHandled = 0; static int BSDSignal = 0; static int BSDCode = 0; static struct sigcontext *BSDSigcontext = NULL; static pthread_t BSDPthread = NULL; static int PosixHandled = 0; static int PosixSignal = 0; static siginfo_t *PosixInfo = NULL; static void *PosixContext = NULL; static pthread_t PosixPthread = NULL; /* a mutex for all the threads to wait on */ static pthread_mutex_t mutex; /* three possible signal handlers. See man sigaction. */ /* ANSI signal handler prototype */ static void ANSIHandler(int sig) { ANSIHandled = 1; ANSISignal = sig; ANSIPthread = pthread_self(); } /* BSD signal handler prototype */ static void BSDHandler(int sig, int code, struct sigcontext *scp) { BSDHandled = 1; BSDSignal = sig; BSDCode = code; BSDSigcontext = scp; BSDPthread = pthread_self(); } /* Posix signal handler prototype */ static void PosixHandler(int sig, siginfo_t *info, void *context) { PosixHandled = 1; PosixSignal = sig; PosixInfo = info; PosixContext = context; PosixPthread = pthread_self(); } /* A function for a thread to run. */ void *ThreadStart(void *arg) { const char *name = (const char *)arg; pthread_t self = pthread_self(); printf("%s is alive: 0x%08x\n", name, self); /* try to lock the mutex. This will sleep for ever */ pthread_mutex_lock(&mutex); } #define ANSISIG SIGUSR1 #define BSDSIG SIGUSR2 #define PosixSIG SIGXFSZ int main(void) { struct sigaction ANSISigaction, BSDSigaction, PosixSigaction; pthread_t ANSIThread, BSDThread, PosixThread; ANSISigaction.sa_handler = ANSIHandler; ANSISigaction.sa_flags = 0; sigaction(ANSISIG, &ANSISigaction, NULL); BSDSigaction.sa_handler = BSDHandler; BSDSigaction.sa_flags = 0; sigaction(BSDSIG, &BSDSigaction, NULL); PosixSigaction.sa_sigaction = PosixHandler; PosixSigaction.sa_flags = SA_SIGINFO; sigaction(PosixSIG, &PosixSigaction, NULL); pthread_mutex_init(&mutex, NULL); pthread_mutex_lock(&mutex); pthread_create(&ANSIThread, NULL, ThreadStart, "ANSI"); pthread_create(&BSDThread, NULL, ThreadStart, "BSD"); pthread_create(&PosixThread, NULL, ThreadStart, "Posix"); printf("ANSI Thread 0x%08x\n", ANSIThread); printf("BSD Thread 0x%08x\n", BSDThread); printf("Posix Thread 0x%08x\n", PosixThread); /* wait for the threads to be alive */ printf("waiting for the threads to be alive\n"); /* I know I could use a pthreads mechanism for this, * but I wanted to keep it simple. */ sleep(5); pthread_kill(ANSIThread, ANSISIG); pthread_kill(BSDThread, BSDSIG); pthread_kill(PosixThread, PosixSIG); /* wait for the signals to be delivered. */ printf("waiting for the signals to be delivered\n"); /* I know I could use a pthreads mechanism for this, * but I wanted to keep it simple. */ sleep(5); printf("ANSI: Handled %d signal %d pthread 0x%08x\n", ANSIHandled, ANSISignal, ANSIPthread); printf("BSD: Handled %d signal %d pthread 0x%08x code %d sigcontext 0x%08x\n", BSDHandled, BSDSignal, BSDPthread, BSDCode, BSDSigcontext); printf("Posix: Handled %d signal %d pthread 0x%08x info 0x%08x context 0x%08x\n", PosixHandled, PosixSignal, PosixPthread, PosixInfo, PosixContext); return 0; } >Fix: Not known. May be related to the fact that _thread_sig_send() (lib/libc_r/uthread/uthread_sig.c) passes 0 as the has_args argument to thread_sig_add(), under certain circumstances. >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200110311229.f9VCT0Q23978>