From nb@thrush.ravenbrook.com  Wed Oct 31 04:29:17 2001
Return-Path: <nb@thrush.ravenbrook.com>
Received: from thrush.ravenbrook.com (thrush.ravenbrook.com [193.112.141.249])
	by hub.freebsd.org (Postfix) with ESMTP id 417BB37B403
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 31 Oct 2001 04:29:16 -0800 (PST)
Received: (from nb@localhost)
	by thrush.ravenbrook.com (8.11.6/8.11.6) id f9VCT0Q23978;
	Wed, 31 Oct 2001 12:29:00 GMT
	(envelope-from nb)
Message-Id: <200110311229.f9VCT0Q23978@thrush.ravenbrook.com>
Date: Wed, 31 Oct 2001 12:29:00 GMT
From: Nicholas Barnes <nb@ravenbrook.com>
Reply-To: Nicholas Barnes <nb@ravenbrook.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc: mps-staff@ravenbrook.com
Subject: pthread_kill signal handler doesn't get sigcontext or ucontext
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         31661
>Category:       bin
>Synopsis:       pthread_kill signal handler doesn't get sigcontext or ucontext
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-threads
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 31 04:30:06 PST 2001
>Closed-Date:    Wed Feb 04 07:51:54 PST 2004
>Last-Modified:  Wed Feb 04 07:51:54 PST 2004
>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:

From: Nick Barnes <nb@ravenbrook.com>
To: freebsd-gnats-submit@FreeBSD.org
Cc: mps-staff@ravenbrook.com
Subject: Re: bin/31661: pthread_kill signal handler doesn't get sigcontext or ucontext
Date: Thu, 01 Nov 2001 12:55:54 +0000

 I forgot to provide the results of running the test program.  Here
 they are.  The bug is demonstrated by the last two lines of output:
 the code, sigcontext, info, and context variables are all zero.
 
 $ cc -pthread test.c
 test.c: In function `main':
 test.c:87: warning: assignment from incompatible pointer type
 $ ./a.out
 ANSI Thread  0x0804c400
 BSD Thread   0x0804cc00
 Posix Thread 0x0805f000
 waiting for the threads to be alive
 ANSI is alive: 0x0804c400
 BSD is alive: 0x0804cc00
 Posix is alive: 0x0805f000
 waiting for the signals to be delivered
 ANSI:  Handled 1 signal 30 pthread 0x0804c400
 BSD:   Handled 1 signal 31 pthread 0x0804cc00 code 0 sigcontext 0x00000000
 Posix: Handled 1 signal 25 pthread 0x0805f000 info 0x00000000 context 0x00000000
 $ 
Responsible-Changed-From-To: freebsd-bugs->jasone 
Responsible-Changed-By: jasone 
Responsible-Changed-When: Mon Dec 17 11:36:14 PST 2001 
Responsible-Changed-Why:  
I'll take a look at this. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=31661 
Responsible-Changed-From-To: jasone->freebsd-bugs 
Responsible-Changed-By: jasone 
Responsible-Changed-When: Sat May 11 15:22:53 PDT 2002 
Responsible-Changed-Why:  


http://www.freebsd.org/cgi/query-pr.cgi?pr=31661 
Responsible-Changed-From-To: freebsd-bugs->freebsd-threads 
Responsible-Changed-By: kris 
Responsible-Changed-When: Sat Jul 12 18:36:45 PDT 2003 
Responsible-Changed-Why:  
Assign to threads mailing list 

http://www.freebsd.org/cgi/query-pr.cgi?pr=31661 

From: Craig Rodrigues <rodrigc@crodrigues.org>
To: freebsd-gnats-submit@FreeBSD.org
Cc: nb@ravenbrook.com, mps-staff@ravenbrook.com
Subject: Re: bin/31661: pthread_kill signal handler doesn't get sigcontext or ucontext
Date: Mon, 2 Feb 2004 16:39:30 -0500

 Hi,
 
 I just tried your test program on FreeBSD-CURRENT.
 
 When linked with -lc_r, the output is:
 
 NSI Thread  0x0804c400
 BSD Thread   0x0804cc00
 Posix Thread 0x0805f000
 waiting for the threads to be alive
 ANSI is alive: 0x0804c400
 BSD is alive: 0x0804cc00
 Posix is alive: 0x0805f000
 waiting for the signals to be delivered
 ANSI:  Handled 1 signal 30 pthread 0x0804c400
 BSD:   Handled 1 signal 31 pthread 0x0804cc00 code 0 sigcontext 0x00000000
 Posix: Handled 1 signal 25 pthread 0x0805f000 info 0x00000000 context 0x00000000
 
 
 
 When linked with -lpthread, the output is:
 
 ANSI Thread  0x08053400
 BSD Thread   0x08053600
 Posix Thread 0x08053800
 waiting for the threads to be alive
 ANSI is alive: 0x08053400
 BSD is alive: 0x08053600
 Posix is alive: 0x08053800
 waiting for the signals to be delivered
 ANSI:  Handled 1 signal 30 pthread 0x08053400
 BSD:   Handled 1 signal 31 pthread 0x08053600 code 0 sigcontext 0xbfaddbe8
 Posix: Handled 1 signal 25 pthread 0x08053800 info 0xbfacdb58 context 0xbfacdbe8
 
 
 You mentioned that the bug is demonstrated by the fact
 that sigcontext and context are 0 in the last two lines of the output.
 
 This problem does not seem to exist for the new pthread library.
 
 -- 
 Craig Rodrigues        
 rodrigc@crodrigues.org

From: Nick Barnes <nb@ravenbrook.com>
To: Craig Rodrigues <rodrigc@crodrigues.org>
Cc: freebsd-gnats-submit@FreeBSD.org, mps-staff@ravenbrook.com
Subject: Re: bin/31661: pthread_kill signal handler doesn't get sigcontext or ucontext 
Date: Mon, 02 Feb 2004 21:50:13 +0000

 At 2004-02-02 21:39:30+0000, Craig Rodrigues writes:
 
 > This problem does not seem to exist for the new pthread library.
 
 Great, thanks!  I must try out -CURRENT.
 
 The underlying functionality is essential for some applications
 (basically anything which needs to pause other threads in order to
 introspect on their stacks, e.g. for garbage collection).
 
 Nick B
State-Changed-From-To: open->closed 
State-Changed-By: deischen 
State-Changed-When: Wed Feb 4 07:47:36 PST 2004 
State-Changed-Why:  
This is written against libc_r's implementation of pthread_kill; 
libpthread does provide full signal handler arguments to pthread_kill. 
Still it iw worth noting that trying to do anything sane with 
a context from a pthread_kill() is probably not what you want 
especially for scope process threads.  pthread_kill() is a 
simulated interrupt and the threads interrupted context is generated 
by the threads library -- it is not like a real signal interrupted 
the thread while it was running. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=31661 
>Unformatted:
