This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Async cancellation and destructors


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.




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]