diff options
author | Rich Felker <dalias@aerifal.cx> | 2011-04-17 17:06:05 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2011-04-17 17:06:05 -0400 |
commit | 1ebde9c3a228e8daa4bdba98046556b4b6829f5e (patch) | |
tree | 61ed4895a116fae89024e73079618a904fb05958 /src/thread | |
parent | 9080cc153cc2b09881c3245becbd68534db18d7c (diff) | |
download | musl-1ebde9c3a228e8daa4bdba98046556b4b6829f5e.tar.gz musl-1ebde9c3a228e8daa4bdba98046556b4b6829f5e.tar.xz musl-1ebde9c3a228e8daa4bdba98046556b4b6829f5e.zip |
fix pthread_exit from cancellation handler
cancellation frames were not correctly popped, so this usage would not only loop, but also reuse discarded and invalid parts of the stack.
Diffstat (limited to 'src/thread')
-rw-r--r-- | src/thread/pthread_create.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 8e3a4a26..c6a23955 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -18,12 +18,13 @@ weak_alias(dummy_1, __pthread_tsd_run_dtors); void __pthread_unwind_next(struct __ptcb *cb) { - pthread_t self; + pthread_t self = pthread_self(); int n; - if (cb->__next) longjmp((void *)cb->__next->__jb, 1); - - self = pthread_self(); + if (cb->__next) { + self->cancelbuf = cb->__next->__next; + longjmp((void *)cb->__next->__jb, 1); + } LOCK(&self->exitlock); @@ -104,7 +105,6 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo new->detached = attr->_a_detach; new->attr = *attr; new->unblock_cancel = self->cancel; - new->result = PTHREAD_CANCELED; memcpy(new->tlsdesc, self->tlsdesc, sizeof new->tlsdesc); new->tlsdesc[1] = (uintptr_t)new; stack = (void *)((uintptr_t)new-1 & ~(uintptr_t)15); |