This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Async cancellation and destructors
- From: "Phil Endecott" <spam_from_glibc_help at chezphil dot org>
- To: <libc-help at sourceware dot org>
- Date: Wed, 10 Dec 2008 14:48:09 +0000
- Subject: 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.