| Summary: | libc_r aborts when exiting thread is canceled | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Archie Cobbs <archie> | ||||
| Component: | bin | Assignee: | Archie Cobbs <archie> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 4.5-RELEASE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
|
Description
Archie Cobbs
2002-04-30 23:20:01 UTC
Oops, in that patch the "(_thread_run->flags & PTHREAD_EXITING) != 0" should of course instead be "(_thread_run->flags & PTHREAD_EXITING) == 0". -Archie __________________________________________________________________________ Archie Cobbs * Packet Design * http://www.packetdesign.com Test case below. -Archie __________________________________________________________________________ Archie Cobbs * Packet Design * http://www.packetdesign.com #include <stdio.h> #include <signal.h> #include <unistd.h> #include <errno.h> #include <sched.h> #include <pthread.h> #include <err.h> static void thread_cleanup(void *arg) { sched_yield(); printf("Thread: executing cleanup...\n"); pthread_testcancel(); } static void * thread_main(void *arg) { pthread_cleanup_push(thread_cleanup, NULL); printf("Thread: sleeping 1 second...\n"); sleep(1); printf("Thread: sending SIGTERM...\n"); kill(getpid(), SIGTERM); sched_yield(); printf("Thread: exiting...\n"); return (NULL); } int main(int argc, char **argv) { pthread_t tid; sigset_t sigs; int sig; /* Spawn thread */ printf("Main: spawning thread...\n"); if ((errno = pthread_create(&tid, NULL, thread_main, NULL)) != 0) err(1, "pthread_create"); /* Wait for signal */ sigemptyset(&sigs); sigaddset(&sigs, SIGINT); sigaddset(&sigs, SIGTERM); if (sigprocmask(SIG_BLOCK, &sigs, NULL) == -1) err(1, "sigprocmask"); printf("Main: waiting for signal...\n"); if (sigwait(&sigs, &sig) == -1) err(1, "sigwait"); /* Cancel thread */ printf("Main: canceling thread...\n"); pthread_cancel(tid); /* Done */ usleep(500); printf("Main: exiting...\n"); return (0); } Oops, my patch is incomplete as pointed out by Daniel Eischen. The combined patchfile (both patches are required) is below. NOTE: these patches are for -stable; -current is very similar. -Archie __________________________________________________________________________ Archie Cobbs * Packet Design * http://www.packetdesign.com Index: uthread_cancel.c =================================================================== RCS file: /home/cvs/freebsd/src/lib/libc_r/uthread/uthread_cancel.c,v retrieving revision 1.3.2.4 diff -u -r1.3.2.4 uthread_cancel.c --- uthread_cancel.c 19 Aug 2001 11:45:58 -0000 1.3.2.4 +++ uthread_cancel.c 2 May 2002 19:18:37 -0000 @@ -15,7 +15,8 @@ if ((ret = _find_thread(pthread)) != 0) { /* NOTHING */ - } else if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK) { + } else if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK + || (pthread->flags & PTHREAD_EXITING) != 0) { ret = 0; } else { /* Protect the scheduling queues: */ @@ -186,7 +187,8 @@ pthread_testcancel(void) { if (((_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) && - ((_thread_run->cancelflags & PTHREAD_CANCELLING) != 0)) { + ((_thread_run->cancelflags & PTHREAD_CANCELLING) != 0) && + ((_thread_run->flags & PTHREAD_EXITING) == 0)) { /* * It is possible for this thread to be swapped out * while performing cancellation; do not allow it Responsible Changed From-To: freebsd-bugs->archie Assign bug to me since I'm fixing it. State Changed From-To: open->closed Fixed in -current and -stable. |