diff -Nur --exclude=.svn --exclude=aclocal.m4 --exclude='*x3*' --exclude=DEADJOE --exclude=configure --exclude='Makefile*' --exclude='*~' ../../dgcc/d/phobos/internal/gc/gcx.d ./internal/gc/gcx.d
--- ../../dgcc/d/phobos/internal/gc/gcx.d	2008-01-30 11:53:18.000000000 +0100
+++ ./internal/gc/gcx.d	2008-01-30 12:24:25.000000000 +0100
@@ -10,6 +10,8 @@
    Modified by David Friedman, July 2006
 */
 
+private import std.gc, std.stack;
+
 // D Garbage Collector implementation
 
 /************** Debugging ***************************/
@@ -1602,7 +1604,7 @@
 	debug(COLLECT_PRINTF) printf("Gcx.fullcollect()\n");
 
 	Thread.pauseAll();
-
+	
 	p_cache = null;
 	size_cache = 0;
 
@@ -1642,6 +1644,7 @@
 
 		if (t && t.getState() == Thread.TS.RUNNING)
 		{
+		    if (t.isSelf()) updateESP(Thread.getESP());
 		    if (noStack && threads.length == 1)
 			break;
 
@@ -1655,32 +1658,9 @@
 			    assert(0);
 			}
 			debug (PRINTF) printf("mt scan stack bot = %x, top = %x\n", context.Esp, t.stackBottom);
-			mark(cast(void *)context.Esp, t.stackBottom);
+			//mark(cast(void *)context.Esp, t.stackBottom);
 			mark(&context.Edi, &context.Eip);
 		    }
-		    else version (GNU)
-		    {
-			if (t.isSelf())
-			    t.stackTop = Thread.getESP();
-
-			//%%fry printf("top=%08x bot=%08x ext=%08x\n", t.stackTop, t.stackBottom, Thread.getESP());//%%try
-			version (STACKGROWSDOWN)
-			    mark(t.stackTop, t.stackBottom);
-			else
-			    mark(t.stackBottom, t.stackTop);
-		    }
-		    else version (linux)
-		    {
-			// The registers are already stored in the stack
-			//printf("Thread: ESP = x%x, stackBottom = x%x, isSelf = %d\n", Thread.getESP(), t.stackBottom, t.isSelf());
-			if (t.isSelf())
-			    t.stackTop = Thread.getESP();
-
-			version (STACKGROWSDOWN)
-			    mark(t.stackTop, t.stackBottom);
-			else
-			    mark(t.stackBottom, t.stackTop);
-		    }
 		}
 	    }
 	}
@@ -1710,6 +1690,15 @@
 	    mark(ranges[n].pbot, ranges[n].ptop);
 	}
 	//log--;
+	// Scan stacks LL
+        auto cur = stacks;
+	while (cur) {
+	    version(STACKGROWSDOWN)
+		mark(cur.value.lastESP, cur.value.End);
+	    else
+		mark(cur.value.Start, cur.value.lastESP);
+	    cur = cur.next;
+	}
 
 	debug(COLLECT_PRINTF) printf("\tscan heap\n");
 	while (anychanges)
diff -Nur --exclude=.svn --exclude=aclocal.m4 --exclude='*x3*' --exclude=DEADJOE --exclude=configure --exclude='Makefile*' --exclude='*~' ../../dgcc/d/phobos/std/stack.d ./std/stack.d
--- ../../dgcc/d/phobos/std/stack.d	1970-01-01 01:00:00.000000000 +0100
+++ ./std/stack.d	2008-01-30 12:23:36.000000000 +0100
@@ -0,0 +1,56 @@
+module std.stack;
+
+struct Stack {
+  void* Start, End;
+  void* lastESP;
+}
+
+struct LinkedList(T) {
+  LinkedList* next;
+  T value;
+}
+
+void ll_push(T, U)(ref T list, U what) {
+  static assert(is(T==LinkedList!(U)*));
+  auto nlist = new LinkedList!(U);
+  nlist.next = list;
+  nlist.value = what;
+  list = nlist;
+}
+
+void ll_delete(T, U)(ref T list, U value) {
+  if (list && list.value == value) { list = list.next; return; }
+  auto cur = list;
+  if (cur) while (cur.next) {
+    if (cur.next.value == value) { cur.next = cur.next.next; return; }
+    cur = cur.next;
+  }
+  throw new Exception("Value not found in linked list!");
+}
+
+LinkedList!(Stack*) *stacks;
+
+import std.stdio;
+Stack* addStack(void* from, void* to) {
+  auto st = new Stack;
+  st.Start=from; st.End=to;
+  ll_push(stacks, st);
+  return st;
+}
+
+void delStack(Stack* which) {
+  ll_delete(stacks, which);
+}
+
+void updateESP(void* newESP) {
+  auto cur = stacks;
+  while (cur) {
+    if (newESP >= cur.value.Start && newESP <= cur.value.End) {
+      cur.value.lastESP = newESP;
+      return;
+    }
+    cur = cur.next;
+  }
+  writefln("ESP (", newESP, ") not in any known stack!");
+  asm { int 3; }
+}
diff -Nur --exclude=.svn --exclude=aclocal.m4 --exclude='*x3*' --exclude=DEADJOE --exclude=configure --exclude='Makefile*' --exclude='*~' ../../dgcc/d/phobos/std/thread.d ./std/thread.d
--- ../../dgcc/d/phobos/std/thread.d	2008-01-30 11:53:18.000000000 +0100
+++ ./std/thread.d	2008-01-29 18:25:23.000000000 +0100
@@ -39,6 +39,7 @@
  */
 
 module std.thread;
+import std.stack;
 
 //debug=thread;
 
@@ -88,6 +89,7 @@
     this(size_t stacksize = 0)
     {
 	this.stacksize = stacksize;
+	stack = addStack(null, null);
     }
 
     /**
@@ -98,6 +100,7 @@
 	this.fp = fp;
 	this.arg = arg;
 	this.stacksize = stacksize;
+        stack = addStack(null, null);
     }
 
     /**
@@ -107,6 +110,7 @@
     {
 	this.dg = dg;
 	this.stacksize = stacksize;
+        stack = addStack(null, null);
     }
 
     /**
@@ -115,7 +119,7 @@
      */
     thread_hdl hdl;
 
-    void* stackBottom;
+    Stack* stack;
 
     /**
      * Create a new thread and start it running. The new thread initializes
@@ -406,7 +410,8 @@
 	int result;
 
 	debug (thread) printf("Starting thread %d\n", t.idx);
-	t.stackBottom = os_query_stackBottom();
+	t.stack.End = os_query_stackBottom();
+        t.stack.Start = t.stack.End - t.stacksize;
 	try
 	{
 	    result = t.run();
@@ -440,7 +445,8 @@
 	t.state = TS.RUNNING;
 	t.id = GetCurrentThreadId();
 	t.hdl = Thread.getCurrentThreadHandle();
-	t.stackBottom = os_query_stackBottom();
+	t.stack.End = os_query_stackBottom();
+        t.stack.Start = t.stack.End - t.stacksize;
 
 	assert(!allThreads[0]);
 	allThreads[0] = t;
@@ -571,8 +577,7 @@
     }
 
     pthread_t id;
-    void* stackBottom;
-    void* stackTop;
+    Stack* stack;
 
     void start()
     {
@@ -594,20 +599,23 @@
 		}
 	    }
 	    nthreads++;
-
-	    state = TS.RUNNING;
-	    int result;
-	    //printf("creating thread x%x\n", this);
-	    //result = pthread_create(&id, null, &threadstart, this);
-	    // Create with thread attributes to allow non-default stack size - Dave Fladebo
-	    result = pthread_create(&id, &threadAttrs, &threadstart, cast(void*)this);
-	    if (result)
-	    {   state = TS.TERMINATED;
+	}
+	
+	state = TS.RUNNING;
+	int result;
+	//printf("creating thread x%x\n", this);
+	//result = pthread_create(&id, null, &threadstart, this);
+	// Create with thread attributes to allow non-default stack size - Dave Fladebo
+	result = pthread_create(&id, &threadAttrs, &threadstart, cast(void*)this);
+	if (result)
+	synchronized(threadLock)
+	{
+		state = TS.TERMINATED;
 		allThreads[idx] = null;
 		idx = -1;
 		error("failed to start");	// BUG: should report errno
-	    }
-	} // %% changed end of sync region
+	}
+	// %% changed end of sync region
 	//printf("t = x%x, id = %d\n", this, id);
     }
 
@@ -790,12 +798,11 @@
 	    }
 	    else
 	    {   int result;
-
+		
 		result = pthread_kill(id, SIGUSR1);
 		if (result)
 		    error("cannot pause");
-		else
-		    flagSuspend.wait();	// wait for acknowledgement
+		else flagSuspend.wait();	// wait for acknowledgement
 	    }
 	}
 	else
@@ -813,7 +820,6 @@
 	    }
 	    else
 	    {   int result;
-
 		result = pthread_kill(id, SIGUSR2);
 		if (result)
 		    error("cannot resume");
@@ -866,7 +872,7 @@
 		    result = pthread_kill(t.id, SIGUSR1);
 		    if (result)
 			getThis().error("cannot pause");
-		    else
+		else
 			npause++;	// count of paused threads
 		}
 	    }
@@ -960,6 +966,7 @@
 
 	if (pthread_cond_init(&waitCond, null))
 	    error("cannot initialize wait condition");
+	stack = addStack(null, null);
     }
 
     /************************************************
@@ -976,11 +983,14 @@
 	// Need to set t.id here, because thread is off and running
 	// before pthread_create() sets it.
 	t.id = pthread_self();
+        t.stack.End = getESP();
+        size_t stacksize;
+        pthread_attr_getstacksize(&t.threadAttrs, &stacksize);
+        t.stack.Start = t.stack.End - stacksize; // accurate enough
 
 	version(skyos)
 	    installSignalHandlers();
 
-	t.stackBottom = getESP();
 	try
 	{
 	    if(t.state == TS.RUNNING)
@@ -1018,7 +1028,10 @@
 
 	t.state = TS.RUNNING;
 	t.id = pthread_self();
-	t.stackBottom = cast(void*) _d_gcc_query_stack_origin();
+	t.stack.End = cast(void*) _d_gcc_query_stack_origin();
+        size_t stacksize;
+        pthread_attr_getstacksize(&t.threadAttrs, &stacksize);
+        t.stack.Start = t.stack.End - stacksize;
 
 	assert(!allThreads[0]);
 	allThreads[0] = t;
@@ -1092,7 +1105,7 @@
 	    assert(result == 0);
 
 	    Thread t = getThis();
-	    t.stackTop = getESP();
+            updateESP(getESP());
 	    t.flags &= ~1;
 	    flagSuspend.signal();
 	    while (1)
@@ -1145,8 +1160,7 @@
 	private static Thread _instance;
 	static uint nthreads = 1;
 
-	void* stackBottom;
-	void* stackTop;
+	Stack* stack;
 	enum TS
 	{
 	    INITIAL,
