diff --git a/src/gc.c b/src/gc.c
index 5df8d9d24b37286f4c0225ce3333a86fb9ba77ee..0c9f301efb460d76397d7b64c3e4d7b9c279c41d 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -29,7 +29,7 @@ struct callback *gc_evaluator_callback=0;
 
 #include "block_alloc.h"
 
-RCSID("$Id: gc.c,v 1.76 2000/04/20 09:57:54 hubbe Exp $");
+RCSID("$Id: gc.c,v 1.77 2000/04/21 23:07:10 hubbe Exp $");
 
 /* Run garbage collect approximate every time we have
  * 20 percent of all arrays, objects and programs is
@@ -597,7 +597,7 @@ INT32 real_gc_check(void *a)
     return 0;
   }
 
-  if (Pike_in_gc != 2)
+  if (Pike_in_gc /100 != 1)
     fatal("gc check attempted in pass %d.\n", Pike_in_gc);
 
   if(m->saved_refs != -1)
@@ -727,7 +727,7 @@ int debug_gc_is_referenced(void *a)
 
   if(m->refs + m->xrefs > *(INT32 *)a ||
      (!(m->refs < *(INT32 *)a) && m->xrefs)  ||
-     (Pike_in_gc < 4 && m->saved_refs != -1 && m->saved_refs != *(INT32 *)a))
+     (Pike_in_gc < 300 && m->saved_refs != -1 && m->saved_refs != *(INT32 *)a))
   {
     INT32 refs=m->refs;
     INT32 xrefs=m->xrefs;
@@ -811,7 +811,7 @@ int gc_mark(void *a)
   m=get_marker(debug_malloc_pass(a));
 
 #ifdef PIKE_DEBUG
-  if (Pike_in_gc != 3)
+  if (Pike_in_gc /100 != 2)
     fatal("gc mark attempted in pass %d.\n", Pike_in_gc);
 #endif
 
@@ -871,7 +871,7 @@ void do_gc(void)
 #endif
 
   if(Pike_in_gc) return;
-  Pike_in_gc=1;
+  Pike_in_gc=10; /* before pass 1 */
 
   /* Make sure there will be no callback to this while we're in the
    * gc. That can be fatal since this function links objects back to
@@ -910,7 +910,7 @@ void do_gc(void)
 
   init_gc();
 
-  Pike_in_gc=2;
+  Pike_in_gc=100; /* pass one */
   /* First we count internal references */
   gc_check_all_arrays();
   gc_check_all_multisets();
@@ -932,7 +932,7 @@ void do_gc(void)
    */
   call_callback(& gc_callbacks, (void *)0);
 
-  Pike_in_gc=3;
+  Pike_in_gc=200; /* pass two */
   /* Next we mark anything with external references */
   gc_mark_all_arrays();
   run_queue(&gc_mark_queue);
@@ -951,7 +951,7 @@ void do_gc(void)
 #ifdef PIKE_DEBUG
   check_for=(void *)1;
 #endif
-  Pike_in_gc=5;
+  Pike_in_gc=350; /* pass 3.5 */
   /* Now we free the unused stuff */
 
 
@@ -959,13 +959,13 @@ void do_gc(void)
   gc_free_all_unreferenced_multisets();
   gc_free_all_unreferenced_mappings();
   gc_free_all_unreferenced_programs();
-  Pike_in_gc=4;
+  Pike_in_gc=300;
   /* This is intended to happen before the freeing done above. But
    * it's put here for the time being, since the problem of non-object
    * objects getting external references from destroy code isn't
    * solved yet. */
   destroyed = gc_destroy_all_unreferenced_objects();
-  Pike_in_gc=5;
+  Pike_in_gc=350;
   destructed = gc_free_all_unreferenced_objects();
 
 #ifdef PIKE_DEBUG
@@ -978,7 +978,7 @@ void do_gc(void)
 
   exit_gc();
 
-  Pike_in_gc=6;
+  Pike_in_gc=400;
   destruct_objects_to_destruct();
   
   objects_freed -= (double) num_objects;
diff --git a/src/interpret.c b/src/interpret.c
index 1a4363af82867fe768498f2d8039be9ff4aa2542..9e9910531b176f180251c0957f71ea916a62c5c9 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.146 2000/04/21 20:08:08 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.147 2000/04/21 23:07:10 hubbe Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -491,6 +491,9 @@ struct backlog
   INT32 arg,arg2;
   struct program *program;
   unsigned char *pc;
+#ifdef _REENTRANT
+  struct object *thread_id;
+#endif
 };
 
 struct backlog backlog[BACKLOG];
@@ -516,9 +519,14 @@ void dump_backlog(void)
       file=get_line(backlog[e].pc-1,backlog[e].program, &line);
       if(backlog[e].instruction < 0 || backlog[e].instruction+F_OFFSET > F_MAX_OPCODE)
       {
-	fprintf(stderr,"%s:%ld: ILLEGAL INSTRUCTION %d\n",
+	fprintf(stderr,"%s:%ld: %p ILLEGAL INSTRUCTION %d\n",
 		file,
 		(long)line,
+#ifdef _REENTRANT
+		backlog[e].thread_id,
+#else
+		0,
+#endif
 		backlog[e].instruction + F_OFFSET);
 	continue;
       }
@@ -526,24 +534,39 @@ void dump_backlog(void)
 
       if(instrs[backlog[e].instruction].flags & I_HASARG2)
       {
-	fprintf(stderr,"%s:%ld: %s(%ld,%ld)\n",
+	fprintf(stderr,"%s:%ld: %p %s(%ld,%ld)\n",
 		file,
 		(long)line,
+#ifdef _REENTRANT
+		backlog[e].thread_id,
+#else
+		0,
+#endif
 		low_get_f_name(backlog[e].instruction + F_OFFSET, backlog[e].program),
 		(long)backlog[e].arg,
 		(long)backlog[e].arg2);
       }
       else if(instrs[backlog[e].instruction].flags & I_HASARG)
       {
-	fprintf(stderr,"%s:%ld: %s(%ld)\n",
+	fprintf(stderr,"%s:%ld: %p %s(%ld)\n",
 		file,
 		(long)line,
+#ifdef _REENTRANT
+		backlog[e].thread_id,
+#else
+		0,
+#endif
 		low_get_f_name(backlog[e].instruction + F_OFFSET, backlog[e].program),
 		(long)backlog[e].arg);
       }else{
-	fprintf(stderr,"%s:%ld: %s\n",
+	fprintf(stderr,"%s:%ld: %p %s\n",
 		file,
 		(long)line,
+#ifdef _REENTRANT
+		backlog[e].thread_id,
+#else
+		0,
+#endif
 		low_get_f_name(backlog[e].instruction + F_OFFSET, backlog[e].program));
       }
     }
diff --git a/src/interpreter.h b/src/interpreter.h
index ab70f5a472adc20445e5be8002d1f55052aa261d..e51934ad86940e57f4a72a35bc9eba0f5bf7bab4 100644
--- a/src/interpreter.h
+++ b/src/interpreter.h
@@ -78,8 +78,10 @@ static int eval_instruction(unsigned char *pc)
       backlog[backlogp].program=Pike_fp->context.prog;
       add_ref(Pike_fp->context.prog);
       backlog[backlogp].instruction=instr;
-      backlog[backlogp].arg=0;
       backlog[backlogp].pc=pc;
+#ifdef _REENTRANT
+      backlog[backlogp].thread_id=thread_id;
+#endif
 
       debug_malloc_touch(Pike_fp->current_object);
       switch(d_flag)
diff --git a/src/object.c b/src/object.c
index e0a4a44cd0c9fc7cc2ab0d670aec11b6e57de043..fbca5a1e3218b2b0a0571e4a8fca048133f98c98 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: object.c,v 1.117 2000/04/20 02:41:45 hubbe Exp $");
+RCSID("$Id: object.c,v 1.118 2000/04/21 23:07:10 hubbe Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -471,7 +471,7 @@ void low_destruct(struct object *o,int do_free)
 
 #ifdef PIKE_DEBUG
   if(d_flag > 20) do_debug();
-  if(Pike_in_gc > 1 && Pike_in_gc < 4 && Pike_in_gc != 5)
+  if(Pike_in_gc >= 100 && Pike_in_gc < 300)
     fatal("Destructing object inside gc()\n");
 #endif
 
@@ -561,7 +561,7 @@ void destruct_objects_to_destruct(void)
   struct object *o, *next;
 
 #ifdef PIKE_DEBUG
-  if (Pike_in_gc > 1 && Pike_in_gc < 6)
+  if (Pike_in_gc >= 100 && Pike_in_gc < 400)
     fatal("Can't meddle with the object link list in gc pass %d.\n", Pike_in_gc);
 #endif
 
@@ -614,7 +614,7 @@ void really_free_object(struct object *o)
     DOUBLELINK(objects_to_destruct,o);
     if (Pike_in_gc) {
       remove_marker(o);
-      if (Pike_in_gc < 6) return; /* Done last in gc(). */
+      if (Pike_in_gc < 400) return; /* Done last in gc(). */
     }
     if(!destruct_object_evaluator_callback)
     {
diff --git a/src/threads.h b/src/threads.h
index 256559d1f5cd2e2afdc2a991cee548345388a32c..f907dd782e7c20930df45a26ca17c628dfb5608f 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -1,5 +1,5 @@
 /*
- * $Id: threads.h,v 1.87 2000/04/20 01:49:45 mast Exp $
+ * $Id: threads.h,v 1.88 2000/04/21 23:07:10 hubbe Exp $
  */
 #ifndef THREADS_H
 #define THREADS_H
@@ -506,7 +506,7 @@ struct thread_state {
      DO_IF_DEBUG({ \
        if(thread_for_id(th_self()) != thread_id) \
 	 fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id); \
-       if (Pike_in_gc >1 && Pike_in_gc <4) \
+       if (Pike_in_gc >=100 && Pike_in_gc <300) \
 	 fatal("Threads allowed during garbage collection.\n"); \
      }) \
      if(num_threads > 1 && !threads_disabled) { \
@@ -541,7 +541,7 @@ struct thread_state {
      DO_IF_DEBUG({ \
        if(thread_for_id(th_self()) != thread_id) \
 	 fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id); \
-       if (Pike_in_gc >1 && Pike_in_gc <4) \
+       if (Pike_in_gc >=100 && Pike_in_gc <300) \
 	 fatal("Threads allowed during garbage collection.\n"); \
      }) \
      if(num_threads > 1 && !threads_disabled) { \