about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-04-17 17:06:05 -0400
committerRich Felker <dalias@aerifal.cx>2011-04-17 17:06:05 -0400
commit1ebde9c3a228e8daa4bdba98046556b4b6829f5e (patch)
tree61ed4895a116fae89024e73079618a904fb05958 /src
parent9080cc153cc2b09881c3245becbd68534db18d7c (diff)
downloadmusl-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')
-rw-r--r--src/thread/pthread_create.c10
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);