debugging, more pthreads crap
diff --git a/src/libthread/exec-unix.c b/src/libthread/exec-unix.c
index 91639bb..73a2faf 100644
--- a/src/libthread/exec-unix.c
+++ b/src/libthread/exec-unix.c
@@ -50,6 +50,7 @@
 		goto Bad;
 	case 0:
 		efork(fd, pfd, prog, args);
+		_threaddebug(DBGSCHED, "exit after efork");
 		_exit(0);
 	default:
 		_threadafterexec();
@@ -152,6 +153,7 @@
 		strcpy(buf, "exec failed");
 	write(fd[1], buf, strlen(buf));
 	close(fd[1]);
+	_threaddebug(DBGSCHED, "_exits in exec-unix");
 	_exits(buf);
 }
 
diff --git a/src/libthread/id.c b/src/libthread/id.c
index a6d5222..c2aa03d 100644
--- a/src/libthread/id.c
+++ b/src/libthread/id.c
@@ -66,6 +66,7 @@
 	t->name = vsmprint(fmt, arg);
 	va_end(arg);
 
+	_threaddebug(DBGSCHED, "set name %s", t->name);
 /* Plan 9 only 
 	if(p->nthreads == 1){
 		snprint(buf, sizeof buf, "#p/%d/args", getpid());
diff --git a/src/libthread/mkfile b/src/libthread/mkfile
index ede391d..20d08e0 100644
--- a/src/libthread/mkfile
+++ b/src/libthread/mkfile
@@ -50,6 +50,9 @@
 texec: texec.$O $PLAN9/lib/$LIB
 	$LD -o texec texec.$O $LDFLAGS -lthread -l9
 
+tspawn: tspawn.$O $PLAN9/lib/$LIB
+	$LD -o tspawn tspawn.$O $LDFLAGS -lthread -l9
+
 trend: trend.$O $PLAN9/lib/$LIB
 	$LD -o trend trend.$O $LDFLAGS -lthread -l9
 
diff --git a/src/libthread/note.c b/src/libthread/note.c
index 60742aa..94bf236 100644
--- a/src/libthread/note.c
+++ b/src/libthread/note.c
@@ -87,9 +87,7 @@
 	Note *n;
 
 	_threaddebug(DBGNOTE, "Got note %s", s);
-	if(strncmp(s, "sys:", 4) == 0
-	&& strcmp(s, "sys: write on closed pipe") != 0
-	&& strcmp(s, "sys: child") != 0)
+	if(strncmp(s, "sys:", 4) == 0)
 		noted(NDFLT);
 
 //	if(_threadexitsallstatus){
diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c
index b2c1c02..a914f43 100644
--- a/src/libthread/pthread.c
+++ b/src/libthread/pthread.c
@@ -60,6 +60,7 @@
 void
 _threadexitproc(char *exitstr)
 {
+	_threaddebug(DBGSCHED, "_pthreadexit");
 	pthread_exit(nil);
 }
 
@@ -69,7 +70,8 @@
 void
 _threadexitallproc(char *exitstr)
 {
-	exits(0);
+	_threaddebug(DBGSCHED, "_threadexitallproc");
+	exits(exitstr);
 }
 
 /*
@@ -111,6 +113,7 @@
 		else
 			free(w);
 	}
+fprint(2, "_threadwaitproc exits\n");
 }
 
 /* 
diff --git a/src/libthread/sched.c b/src/libthread/sched.c
index 3fb2ff2..55898f0 100644
--- a/src/libthread/sched.c
+++ b/src/libthread/sched.c
@@ -170,9 +170,10 @@
 		/*
 		 * Maybe we were awakened to exit?
 		 */
-		if(_threadexitsallstatus)
+		if(_threadexitsallstatus){
+			_threaddebug(DBGSCHED, "time to exit");
 			_exits(_threadexitsallstatus);
-
+		}
 		assert(q->head != nil);
 	}
 
@@ -291,9 +292,12 @@
 	strncpy(ex, p->exitstr, sizeof ex);
 	ex[sizeof ex-1] = '\0';
 	free(p);
-	if(n == 0)
+	if(n == 0){
+		_threaddebug(DBGSCHED, "procexit; no more procs");
 		_threadexitallproc(ex);
-	else
+	}else{
+		_threaddebug(DBGSCHED, "procexit");
 		_threadexitproc(ex);
+	}
 }
 
diff --git a/src/libthread/ucontext.c b/src/libthread/ucontext.c
index b1c5ef5..98e92cc 100644
--- a/src/libthread/ucontext.c
+++ b/src/libthread/ucontext.c
@@ -1,5 +1,12 @@
 #include "threadimpl.h"
 
+static void
+launcher(void (*f)(void*), void *arg)
+{
+	f(arg);
+	threadexits(nil);
+}
+
 void
 _threadinitstack(Thread *t, void (*f)(void*), void *arg)
 {
@@ -17,7 +24,7 @@
 	/* leave a few words open on both ends */
 	t->context.uc.uc_stack.ss_sp = t->stk+8;
 	t->context.uc.uc_stack.ss_size = t->stksize-16;
-	makecontext(&t->context.uc, (void(*)())f, 1, arg);
+	makecontext(&t->context.uc, (void(*)())launcher, 2, f, arg);
 }
 
 void