NetBSD Problem Report #25563

Received: (qmail 16329 invoked by uid 605); 14 May 2004 06:01:48 -0000
Message-Id: <20040514060145.2577711159@narn.netbsd.org>
Date: Fri, 14 May 2004 06:01:45 +0000 (UTC)
From: kent@NetBSD.org
Sender: gnats-bugs-owner@NetBSD.org
Reply-To: kent@NetBSD.org
To: gnats-bugs@gnats.NetBSD.org
Subject: pthread crash in signal handler with sigaltstack
X-Send-Pr-Version: www-1.0

>Number:         25563
>Category:       lib
>Synopsis:       pthread crash in signal handler with sigaltstack
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri May 14 06:02:00 +0000 2004
>Closed-Date:    Sat Sep 05 22:48:49 +0000 2015
>Last-Modified:  Sat Sep 05 22:48:49 +0000 2015
>Originator:     TAMURA Kent
>Release:        2.0E i386
>Organization:
NetBSD
>Environment:
NetBSD p4 2.0E NetBSD 2.0E (P4MP) #6: Wed May 12 23:02:09 JST 2004  kent@p4:/sys/arch/i386/compile/P4MP i386
>Description:
Functions of pthread does not work in a signal handler with alternate stack.

>How-To-Repeat:
===================== sample code:  sigtest.c
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

void handler(int signo) {
    printf("ENTER: handler\n");
    fflush(stdout);
    printf("self=%p\n", pthread_self());
    printf("LEAVE: handler\n");
    exit(1);
}

int main() {
    stack_t s;
    s.ss_sp = malloc(SIGSTKSZ);
    s.ss_size = SIGSTKSZ;
    s.ss_flags = 0;
    if (sigaltstack(&s, NULL) < 0)
        perror("sigaltstack()");

    struct sigaction sa;
    sa.sa_flags = SA_ONSTACK;
    sa.sa_handler = handler;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGSEGV, &sa, NULL);
    printf("self=%p\n", pthread_self());
    *(int*)NULL = 1;            // throw SIGSEGV
    return 0;
}

% gcc -g -o sigtest sigtest.c -lpthread

% ./sigtest
self=0xbfa00000
zsh: segmentation fault (core dumped)  ./sigtest

(gdb) bt
#0  0x48068c04 in pthread_spinlock () from /usr/lib/libpthread.so.0
#1  0x4806b118 in pthread_setcancelstate () from /usr/lib/libpthread.so.0
#2  0x481900e6 in __flockfile_internal () from /usr/lib/libc.so.12
#3  0x4818729c in vfprintf () from /usr/lib/libc.so.12
#4  0x48175315 in printf () from /usr/lib/libc.so.12
#5  0x080489bf in handler(int) (signo=11) at sigtest.c:7
#6  <signal handler called>
#7  main () at sigtest.c:28
#8  0x08048752 in ___start ()

>Fix:
To retrieve pthread_self() from the stack pointer is bad idea.

>Release-Note:
>Audit-Trail:
From: Thomas Klausner <wiz@NetBSD.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: lib/25563
Date: Fri, 27 Mar 2009 15:28:11 +0100

 I just tried the program from this PR on 5.99.8/amd64, and it said:
 self=0x7f7fffe00000
 ENTER: handler
 self=0x7f7ffd800000
 LEAVE: handler

 No segfault.

 I'm not sure what this says about the reported problem, so it's just
 an FYI.
  Thomas

From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: lib/25563
Date: Fri, 27 Mar 2009 22:03:12 +0000

 On Fri, Mar 27, 2009 at 02:30:03PM +0000, Thomas Klausner wrote:
  > I just tried the program from this PR on 5.99.8/amd64, and it said:
  > self=0x7f7fffe00000
  > ENTER: handler
  > self=0x7f7ffd800000
  > LEAVE: handler
  >  
  > No segfault.

 I'd be surprised if this issue affected the new threads library; the
 question I guess is if it still affects 4.0_STABLE.

 -- 
 David A. Holland
 dholland@netbsd.org

From: Andrew Doran <ad@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: lib/25563
Date: Fri, 27 Mar 2009 22:49:26 +0000

 On Fri, Mar 27, 2009 at 10:05:05PM +0000, David Holland wrote:

 >  On Fri, Mar 27, 2009 at 02:30:03PM +0000, Thomas Klausner wrote:
 >   > I just tried the program from this PR on 5.99.8/amd64, and it said:
 >   > self=0x7f7fffe00000
 >   > ENTER: handler
 >   > self=0x7f7ffd800000
 >   > LEAVE: handler
 >   >  
 >   > No segfault.
 >  
 >  I'd be surprised if this issue affected the new threads library; the
 >  question I guess is if it still affects 4.0_STABLE.

 It still does unfortunatley. We need thread local storage to sort it; TLS
 would be used for pthread__self(). I have a kernel change to make this a bit
 easier. _lwp_setprivate() calls into MD code to have it set up whatever fast
 path the architecture provides. I should commit this. Another change that I
 have not written is this: ucontext_t also needs an addtional field for the
 LWP private pointer (why this doesn't have a spare field available is, well,
 a depressing question). However, someone still needs to add support to the
 dynamic linker, C library and toolchain. There is interest in doing this,
 however no firm progress to date.

From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: lib/25563
Date: Sat, 28 Mar 2009 03:28:11 +0000

 On Fri, Mar 27, 2009 at 10:50:04PM +0000, Andrew Doran wrote:
  >> On Fri, Mar 27, 2009 at 02:30:03PM +0000, Thomas Klausner wrote:
  >>> I just tried the program from this PR on 5.99.8/amd64, and it said:
  >>> self=0x7f7fffe00000
                  ^^
  >>> ENTER: handler
  >>> self=0x7f7ffd800000
                  ^^
  >>> LEAVE: handler

 Er. Yeah. Given that the program doesn't create any new threads, this
 is clearly wrong, so what I wrote earlier is clearly bollocks. :-/

  > We need thread local storage to sort it; TLS would be used for
  > pthread__self().

 What's supposed to happen if you use sigaltstack in a multithreaded
 program anyway? Is the alternate stack supposed to be per-thread?
 Because if so this is fairly easily fixed even without TLS, and if not
 it's all nasal demons anyway and doesn't matter.

 -- 
 David A. Holland
 dholland@netbsd.org

From: Andrew Doran <ad@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: lib/25563
Date: Sat, 28 Mar 2009 20:43:58 +0000

 On Sat, Mar 28, 2009 at 03:30:04AM +0000, David Holland wrote:

 >  What's supposed to happen if you use sigaltstack in a multithreaded
 >  program anyway? Is the alternate stack supposed to be per-thread?

 Pretty much everything about signals is per-thread except for the signal
 disposition and job control.

 pthreads isn't signal handler safe. That is to say, you can't go calling
 pthread_create() from a signal handler. In reality a limited set of stuff
 _should_ work, say pthread_self() and pthread_kill(), because there are
 buggy applications that expect them to work.

 We have system calls stubs in the thread library for cancellation. They are
 defined to be signal handler safe yet must use pthread__self(), so even if
 we ignore the above case we need to fix it for libpthread itself to work
 correctly (assuming the cancellation implementation remains unchanged).

 There is another nasty. pthread__cancelled() can't work correctly in a
 signal handler, because it has to take locks. And another nasty: we have
 any number of routines in libc that can interrupted and cancelled while
 holding locks.

 That's enough depressing thought for tonight, I am going to go back to
 enjoying my beer.

From: Andrew Doran <ad@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: lib/25563
Date: Sat, 28 Mar 2009 21:02:52 +0000

 One more kick in the nuts: doing TLS on NetBSD means inventing and
 publishing a TLS spec for vax/elf, implementing said spec in binutils/gcc.

 Searching the web throws up mention of an existing proposal for m68k. I
 do not know how far that has progressed.

From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: lib/25563
Date: Sun, 29 Mar 2009 00:39:11 +0000

 On Sat, Mar 28, 2009 at 08:45:01PM +0000, Andrew Doran wrote:
  > From: Andrew Doran <ad@netbsd.org>
  > To: gnats-bugs@NetBSD.org
  > Cc: 
  > Subject: Re: lib/25563
  > Date: Sat, 28 Mar 2009 20:43:58 +0000
  > 
  >  On Sat, Mar 28, 2009 at 03:30:04AM +0000, David Holland wrote:
  >  
  >>  What's supposed to happen if you use sigaltstack in a multithreaded
  >>  program anyway? Is the alternate stack supposed to be per-thread?
  >  
  >  Pretty much everything about signals is per-thread except for the signal
  >  disposition and job control.

 In that case, probably the right answer for the time being is to set
 an interval tree (or some such) that maps from stack ranges to
 threads. It won't be very fast, but it'll work... and will allow
 supporting different-sized thread stacks.

 Or we could have the pthreads sigaltstack reject any stack that isn't
 exactly SIGSTKSZ, and have SIGSTKSZ be the pthread stack size, and
 then one line of code in pthread__self or so would make it all work.


 Hrm, I wonder if PIE can be abused to provide TLS...

 -- 
 David A. Holland
 dholland@netbsd.org

State-Changed-From-To: open->feedback
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sat, 05 Sep 2015 20:33:43 +0000
State-Changed-Why:
Is this still an issue? We've had TLS for a long time now, and the 4.x
thread library is ancient history.


From: Joerg Sonnenberger <joerg@britannica.bec.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: lib/25563 (pthread crash in signal handler with sigaltstack)
Date: Sat, 5 Sep 2015 23:28:01 +0200

 On Sat, Sep 05, 2015 at 08:33:44PM +0000, dholland@NetBSD.org wrote:
 > State-Changed-From-To: open->feedback
 > State-Changed-By: dholland@NetBSD.org
 > State-Changed-When: Sat, 05 Sep 2015 20:33:43 +0000
 > State-Changed-Why:
 > Is this still an issue? We've had TLS for a long time now, and the 4.x
 > thread library is ancient history.

 It can be closed, nothing in libpthread uses the stack as thread id.
 Platforms without TLS support still call the kernel to obtain the TCB.

 Joerg

State-Changed-From-To: feedback->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sat, 05 Sep 2015 22:48:49 +0000
State-Changed-Why:
PR is obsolete.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.