public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug nptl/415] New: pthread_cancel does not unwind stack when thread is cancelled inside signal handler
@ 2004-09-29 19:04 yufeng_xiong at ltx dot com
  2004-09-29 19:08 ` [Bug nptl/415] " yufeng_xiong at ltx dot com
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: yufeng_xiong at ltx dot com @ 2004-09-29 19:04 UTC (permalink / raw)
  To: glibc-bugs

The New NPTL is specifically designed to solve the problem with thread
cancellation (pthread_cancel) or pthread_exit does not unwind thread stack (so
thread local objects are not destructed) problem, I've tested and it works great
if a thread is cancelled while it is in it's normal execution; however, I tested
that if the thread is cancelled while it is inside it's signal handler, the
thread stack still does not unwind, I think this is a very serious bug since
NPTL is designed to solve this issue.

The following is a simple test case:

//////////////////////////////////////////////////////////////////////
//
// Author: Yufeng Xiong
// pthread_cancel.cxx  --  
// 
//////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>

class Test
{
private:
  int var;
public:
  Test(int i= 0) : var(i) { printf("Test %d created!\n", var); }
  ~Test() { printf("Test %d destructed!\n", var); }
};

extern "C" {
void * Thread(void *)
{
  //ignore SIGALRM
  sigset_t sigs;
  pthread_sigmask(SIG_SETMASK, NULL, &sigs);
  sigaddset(&sigs, SIGALRM);
  pthread_sigmask(SIG_SETMASK, &sigs, NULL);
  Test One(1), Two(2);
  sleep(1000000); //pause - wait to be cancelled
  return (void *)0;
}

void sighand(int signo)
{
  printf("Caught signal\n");
  sleep(1000000); //wait to be cancelled
  return;
}
}

//main test, pass argv[1] = 0 or no argument to test cancel
//in normal execution, pass argv[1] = 1 to test cancel in
//thread signal handler
//to compile: $CC -D_POSIX_C_SOURCE=199506L -g -o pthread_cancel
pthread_cancel.cxx -lpthread
//expected results
/* case 1
./pthread_cancel 
Set up the SIGUSR1 handler for the process
Test 1 created!
Test 2 created!
Main thread cancel!
Test 2 destructed!
Test 1 destructed!
*/
/* case 2
./pthread_cancel 1
Set up the SIGUSR1 handler for the process
Test 1 created!
Test 2 created!
Main thread send signal!
Main thread cancel!
Caught signal
Test 2 destructed!
Test 1 destructed!
*/

int main(int argc, char **argv)
{
  struct sigaction actions;
  printf("Set up the SIGUSR1 handler for the process\n");
 
  sigemptyset(&actions.sa_mask);
  actions.sa_flags = 0;
  actions.sa_handler = sighand;
  sigaction(SIGUSR1,&actions,NULL);  

  pthread_t thr = 0;
  pthread_create(&thr, NULL, Thread, NULL);

  //seems can not use sleep or nanosleep to yield execution
  //because that may interfere with pause call
  sleep(1); //give the thread chance to run
  
  //if passed argv[1] = 1, send signal first
  if (argc > 1 && strcmp(argv[1], "1") == 0)
  {
      printf("Main thread send signal!\n");
      pthread_kill(thr, SIGUSR1);
  }
  //cancel the thread, if signal is sent, thread 'thr' 
  //should be in it's signal handler, otherwise it is in
  //it's normal exeuction, both case it is 'pausing' and
  //can be safely cancelled
  if (pthread_kill(thr, 0) == 0)
  {
      printf("Main thread cancel!\n");
      pthread_cancel(thr);
  }
  pthread_join(thr, (void **)0);

  return 0;
}

-- 
           Summary: pthread_cancel does not unwind stack when thread is
                    cancelled inside signal handler
           Product: glibc
           Version: 2.3.3
            Status: NEW
          Severity: critical
          Priority: P1
         Component: nptl
        AssignedTo: drepper at redhat dot com
        ReportedBy: yufeng_xiong at ltx dot com
                CC: glibc-bugs at sources dot redhat dot com
 GCC build triplet: i686-redhat-linux-gnu
  GCC host triplet: i686-redhat-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://sources.redhat.com/bugzilla/show_bug.cgi?id=415

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug nptl/415] pthread_cancel does not unwind stack when thread is cancelled inside signal handler
  2004-09-29 19:04 [Bug nptl/415] New: pthread_cancel does not unwind stack when thread is cancelled inside signal handler yufeng_xiong at ltx dot com
@ 2004-09-29 19:08 ` yufeng_xiong at ltx dot com
  2004-10-01  8:56 ` drepper at redhat dot com
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: yufeng_xiong at ltx dot com @ 2004-09-29 19:08 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From yufeng_xiong at ltx dot com  2004-09-29 19:08 -------
Created an attachment (id=210)
 --> (http://sources.redhat.com/bugzilla/attachment.cgi?id=210&action=view)
Test Case


-- 


http://sources.redhat.com/bugzilla/show_bug.cgi?id=415

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug nptl/415] pthread_cancel does not unwind stack when thread is cancelled inside signal handler
  2004-09-29 19:04 [Bug nptl/415] New: pthread_cancel does not unwind stack when thread is cancelled inside signal handler yufeng_xiong at ltx dot com
  2004-09-29 19:08 ` [Bug nptl/415] " yufeng_xiong at ltx dot com
@ 2004-10-01  8:56 ` drepper at redhat dot com
  2004-10-01 13:12 ` yufeng_xiong at ltx dot com
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: drepper at redhat dot com @ 2004-10-01  8:56 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From drepper at redhat dot com  2004-10-01 08:56 -------
What you want is completely bogus, this never can work anywhere reliably.  Which
is why it is not required in POSIX.

The only thing which might have to be done is to disable cancellation while the
signal handler is executed.  And even that might not be required.

If your code depends on cancellation in signal handlers, you better rewrite it.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|critical                    |normal
             Status|NEW                         |ASSIGNED
  GCC build triplet|i686-redhat-linux-gnu       |i686-redhat-linux-gnu
           Priority|P1                          |P2


http://sources.redhat.com/bugzilla/show_bug.cgi?id=415

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug nptl/415] pthread_cancel does not unwind stack when thread is cancelled inside signal handler
  2004-09-29 19:04 [Bug nptl/415] New: pthread_cancel does not unwind stack when thread is cancelled inside signal handler yufeng_xiong at ltx dot com
  2004-09-29 19:08 ` [Bug nptl/415] " yufeng_xiong at ltx dot com
  2004-10-01  8:56 ` drepper at redhat dot com
@ 2004-10-01 13:12 ` yufeng_xiong at ltx dot com
  2004-10-01 14:22 ` yufeng_xiong at ltx dot com
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: yufeng_xiong at ltx dot com @ 2004-10-01 13:12 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From yufeng_xiong at ltx dot com  2004-10-01 13:12 -------
(In reply to comment #2)
> What you want is completely bogus, this never can work anywhere reliably.  
Which
> is why it is not required in POSIX.
> The only thing which might have to be done is to disable cancellation while 
the
> signal handler is executed.  And even that might not be required.
> If your code depends on cancellation in signal handlers, you better rewrite 
it.

Hi Ulrich,

Thanks very much for replying to my report.

I have some different opinion, the truth is that POSIX thread standard does not 
talk about objects at all, it is a C-based standard, however, the MT-
programming community tend to agree pthread_cancel and pthread_exit should 
cause a thread stack unwind and all stack based objects be destructed, and your 
NPTL is specifically designed to achieve this goal (solve the early GNU 
compiler/LinuxThread problem), I would expect this to work no matter where/how 
it is called. This works perfectly fine using SUN's Workshop compiler (6.2) on 
Solaris system.

I totally agree this is not a natural thing to do, but extreme cases require 
extreme solution. In my case, it is required that a running thread is able to 
be terminated no matter what, we normally use a flag to achieve this, but that 
can not be 100% reliable given there are third party code and customer code, on 
second stage we try pthread_cancel (with the default deferred cancellation 
type), and this is also not 100% reliable since the thread may not hit a 
cancellation point for a long time, so we try this third stage, using a signal 
to break the thread and make it cancelled inside the signal handler, we can 
also make the thread call pthread_exit inside the signal handler, but the 
standard says it's not safe to do so, and also pthread_exit has the same thread 
unwind problem as pthread_cancel inside signal handler on Linux. Note that we 
don't want to async cancellation because we believe it is not as safe as the 
deferred cancellation.

Note that POSIX standard does not say a thread can not be cancelled inside a 
signal handler, nor does it say it is unsafe to cancel a thread when it is 
inside it's signal handler, that's why I think it should work just as a normal 
cancellation.

On the other hand, is there a technical reason that it can not be done at all? 
or it's just you feel so strongly object to this type of programming make you 
not willing to do it? My understanding is that pthread_cancel is usually also 
implemented as sending a signal (SIGCANCEL), which may be trapped at the kernel 
lever and not get into user thread (like a normal signal does), but it does 
have some similarity with a regular signal behavior, so why a normal 
cancellation works fine, but once the thread goes into it's signal handler, 
then it can be cancelled but thread stack can not be unwind? It sounds to me it 
is doable (Note I'm not very falimiar with Linux, and I don't know anything 
about Linux Kernel and NPTL implementation at all, so those are just my 
assumptions).

Thanks very much for communicating with me.

Best Regards,

Yufeng


-- 


http://sources.redhat.com/bugzilla/show_bug.cgi?id=415

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug nptl/415] pthread_cancel does not unwind stack when thread is cancelled inside signal handler
  2004-09-29 19:04 [Bug nptl/415] New: pthread_cancel does not unwind stack when thread is cancelled inside signal handler yufeng_xiong at ltx dot com
                   ` (2 preceding siblings ...)
  2004-10-01 13:12 ` yufeng_xiong at ltx dot com
@ 2004-10-01 14:22 ` yufeng_xiong at ltx dot com
  2004-10-04 13:42 ` yufeng_xiong at ltx dot com
  2004-10-07 10:52 ` drepper at redhat dot com
  5 siblings, 0 replies; 7+ messages in thread
From: yufeng_xiong at ltx dot com @ 2004-10-01 14:22 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From yufeng_xiong at ltx dot com  2004-10-01 14:22 -------
Dear Ulrich,

I want to make one correction: I tried call pthread_exit from the signal 
handler and it works, thread stack unwinds and local objects get destructed, 
that's good news.

Now the question is that since the standard says all Pthread functions are not 
safe to be used inside signal handler, how safe it is in reality to use 
pthread_exit inside signal handler on Linux using NPTL?

Thanks very much.

Yufeng

-- 


http://sources.redhat.com/bugzilla/show_bug.cgi?id=415

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug nptl/415] pthread_cancel does not unwind stack when thread is cancelled inside signal handler
  2004-09-29 19:04 [Bug nptl/415] New: pthread_cancel does not unwind stack when thread is cancelled inside signal handler yufeng_xiong at ltx dot com
                   ` (3 preceding siblings ...)
  2004-10-01 14:22 ` yufeng_xiong at ltx dot com
@ 2004-10-04 13:42 ` yufeng_xiong at ltx dot com
  2004-10-07 10:52 ` drepper at redhat dot com
  5 siblings, 0 replies; 7+ messages in thread
From: yufeng_xiong at ltx dot com @ 2004-10-04 13:42 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From yufeng_xiong at ltx dot com  2004-10-04 13:42 -------
Deal Ulrich,

Here is more test results regarding pthread_cancel and pthread_exit cause thread
stack unwind (thread local objects be destructed) behavior on Linux:

1. With the default deferred cancellation: In thread normal execution, it works.
   If the thread is inside it's signal handler and get cancelled, it does not work.

2. If use asyncrhonous cancellation: both cases (thread get cancelled while in
it's normal execution or inside it's signal handler) don't work.

3. If use pthread_exit, both cases (call pthread_exit from it's normal execution
or from it's signal handler) works, and this is independent of the cancellation
type.

So clearly there are some mismatch in the behaviors, I would expect
pthread_cancel and pthread_exit should have the same behavior (just as far as
thread stack unwind behavior is concerned), and this behavior also should not
depend on the cancellation type with pthread_cancel.

Thanks very much.

Yufeng

-- 


http://sources.redhat.com/bugzilla/show_bug.cgi?id=415

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug nptl/415] pthread_cancel does not unwind stack when thread is cancelled inside signal handler
  2004-09-29 19:04 [Bug nptl/415] New: pthread_cancel does not unwind stack when thread is cancelled inside signal handler yufeng_xiong at ltx dot com
                   ` (4 preceding siblings ...)
  2004-10-04 13:42 ` yufeng_xiong at ltx dot com
@ 2004-10-07 10:52 ` drepper at redhat dot com
  5 siblings, 0 replies; 7+ messages in thread
From: drepper at redhat dot com @ 2004-10-07 10:52 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From drepper at redhat dot com  2004-10-07 10:52 -------
What ever you find working or not working is irrelevant here.  It all is
undefined behavior.  You can use it if it works but don't come crying when it
breaks after the next update.  There are no guarantees whatsoever.  POSIX
clearly says (XRAT, page 175):

A correct and complete implementation of cancellation in the presence of
asynchronous signals requires considerable care. An implementation has to push a
cancellation cleanup handler on the cancellation cleanup stack while maintaining
the integrity of the stack data structure. If an asynchronously-generated signal
is posted to the thread during a stack operation, the signal handler cannot
manipulate the cancellation cleanup stack. As a consequence, asynchronous signal
handlers may not cancel threads or otherwise manipulate the cancellation state
of a thread. Threads may, of course, be canceled by another thread that used a
sigwait() function to wait synchronously for an asynchronous signal.


I.e., the application is responsible to not call any interfaces which are
cancellation points in a signal handler if the thread could be canceled.

There is no arguing about making this possible.  It will never happen since it
would amount to making the entire runtime async cancel safe which is completely
unpractical.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|                            |INVALID


http://sources.redhat.com/bugzilla/show_bug.cgi?id=415

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-10-07 10:52 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-09-29 19:04 [Bug nptl/415] New: pthread_cancel does not unwind stack when thread is cancelled inside signal handler yufeng_xiong at ltx dot com
2004-09-29 19:08 ` [Bug nptl/415] " yufeng_xiong at ltx dot com
2004-10-01  8:56 ` drepper at redhat dot com
2004-10-01 13:12 ` yufeng_xiong at ltx dot com
2004-10-01 14:22 ` yufeng_xiong at ltx dot com
2004-10-04 13:42 ` yufeng_xiong at ltx dot com
2004-10-07 10:52 ` drepper at redhat dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).