Skip site navigation (1)Skip section navigation (2)
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>