Async cancellation and destructors

Phil Endecott spam_from_glibc_help@chezphil.org
Wed Dec 10 14:49:00 GMT 2008


Dear Experts,

I don't seem to be able to get C++ destructors to run in 
PTHREAD_CANCEL_ASYNCHRONOUS mode.  Here's some example code:

#include <iostream>
#include <pthread.h>
#include <unistd.h>

using namespace std;

struct report_destruction {
   ~report_destruction() {
     cout << "dtor called\n";
   }
};

void* threadfn_with_testcancel(void*)
{
   report_destruction r;
   while (1) {
     pthread_testcancel();
   }
   return NULL;
}

void* threadfn_with_asynccancel(void*)
{
   report_destruction r;
   pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
   while (1) {
   }
   return NULL;
}

void* threadfn_with_blocking_read(void*)
{
   report_destruction r;
   char buf[64];
   read(0,buf,sizeof(buf));
   return NULL;
}


int main()
{
   pthread_t t;

   // Enable one of these:
   //pthread_create(&t, NULL, &threadfn_with_testcancel, NULL);
   //pthread_create(&t, NULL, &threadfn_with_asynccancel, NULL);
   pthread_create(&t, NULL, &threadfn_with_blocking_read, NULL);

   sleep(1);
   pthread_cancel(t);
   pthread_join(t,NULL);
   sleep(1);
   return 0;
}


With the testcancel and blocking_read variants, the cancelled thread 
executes the destructor correctly.  However with the 
PTHREAD_CANCEL_ASYNCHRONOUS variant I get this:

terminate called without an active exception
Aborted

Here's the tail of strace:

[pid 19683] rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
[pid 19683] rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
[pid 19683] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid 19683] nanosleep({1, 0}, {1, 0})   = 0
[pid 19683] tgkill(19683, 19684, SIGRTMIN) = 0
[pid 19683] futex(0xb7cddbd8, FUTEX_WAIT, 19684, NULL <unfinished ...>
[pid 19684] --- SIGRTMIN (Unknown signal 32) @ 0 (0) ---
[pid 19684] futex(0xb7e21ce8, 0x81 /* FUTEX_??? */, 2147483647) = 0
[pid 19684] write(2, "terminate called without an acti"..., 45terminate 
called without an active exception
) = 45
[pid 19684] rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
[pid 19684] tgkill(19683, 19684, SIGABRT) = 0
[pid 19684] --- SIGABRT (Aborted) @ 0 (0) ---

I guess that it is following the "exception thrown while handling 
exception" path.

Is this supposed to work?  Am I doing something wrong?  Is there any 
way to work around this?


Thanks for any suggestions.

Phil.





More information about the Libc-help mailing list