diff --git a/src/backend.c b/src/backend.c
index f3fe6f8c31a37d5e510e41ff23c8a239e9dc3196..acaca8659d13a4dba447943d64f2df7bef24ffed 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: backend.c,v 1.15 1997/08/30 18:35:21 grubba Exp $");
+RCSID("$Id: backend.c,v 1.16 1997/10/23 03:15:30 hubbe Exp $");
 #include "backend.h"
 #include <errno.h>
 #ifdef HAVE_SYS_TYPES_H
@@ -24,6 +24,8 @@ RCSID("$Id: backend.c,v 1.15 1997/08/30 18:35:21 grubba Exp $");
 #include <sys/select.h>
 #endif
 
+#include <sys/stat.h>
+
 #define SELECT_READ 1
 #define SELECT_WRITE 2
 
@@ -185,8 +187,13 @@ void *query_write_callback_data(int fd)
 }
 
 #ifdef DEBUG
+
+struct callback_list do_debug_callbacks;
+
 void do_debug(void)
 {
+  int e;
+  struct stat tmp;
   extern void check_all_arrays(void);
   extern void check_all_mappings(void);
   extern void check_all_programs(void);
@@ -200,6 +207,32 @@ void do_debug(void)
   check_all_programs();
   verify_all_objects();
   verify_shared_strings_tables();
+
+  call_callback(& do_debug_callbacks, 0);
+
+  for(e=0;e<=max_fd;e++)
+  {
+    if(FD_ISSET(e,&selectors.read) || FD_ISSET(e,&selectors.write))
+    {
+      int ret;
+      do {
+	ret=fstat(e, &tmp);
+      }while(ret < 0 && errno == EINTR);
+
+      if(ret<0)
+      {
+	switch(errno)
+	{
+	  case EBADF:
+	    fatal("Backend filedescriptor is bad.\n");
+	    break;
+	  case ENOENT:
+	    fatal("Backend filedescriptor is not.\n");
+	    break;
+	}
+      }
+    }
+  }
 }
 #endif
 
diff --git a/src/backend.h b/src/backend.h
index 5aded4daa9bba93b8ead886c330b0ba867ea925f..e58a610727d42f9f59c2e74f5818d8f1db809210 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -13,6 +13,7 @@
 extern struct timeval current_time;
 extern struct timeval next_timeout;
 typedef void (*file_callback)(int,void *);
+extern struct callback_list do_debug_callbacks;
 
 /* Prototypes begin here */
 struct selectors;
diff --git a/src/modules/call_out/call_out.c b/src/modules/call_out/call_out.c
index 26526b881cd0a5650bab922402874254ef04bfd4..d508736c673088a0de4b368e2462056f0a47b6d0 100644
--- a/src/modules/call_out/call_out.c
+++ b/src/modules/call_out/call_out.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: call_out.c,v 1.13 1997/08/30 18:36:19 grubba Exp $");
+RCSID("$Id: call_out.c,v 1.14 1997/10/23 03:15:41 hubbe Exp $");
 #include "array.h"
 #include "dynamic_buffer.h"
 #include "object.h"
@@ -46,15 +46,28 @@ static int call_buffer_size;     /* no of pointers in buffer */
 #define CAR(X) (((X)<<1)+1)
 #define CDR(X) (((X)<<1)+2)
 #define PARENT(X) (((X)-1)>>1)
-#define CALL(X) call_buffer[(X)]
+#define CALL(X) (call_buffer[(X)])
 #define CMP(X,Y) my_timercmp(& CALL(X).tv, <, & CALL(Y).tv)
 #define SWAP(X,Y) do{ call_out _tmp=CALL(X); CALL(X)=CALL(Y); CALL(Y)=_tmp; } while(0)
 
+#ifdef DEBUG
+static int inside_call_out=0;
+#define PROTECT_CALL_OUTS() \
+   if(inside_call_out) fatal("Recursive call in call_out module.\n"); \
+   inside_call_out=1
+
+#define UNPROTECT_CALL_OUTS() \
+   inside_call_out=0
+#else
+#define PROTECT_CALL_OUTS()
+#define UNPROTECT_CALL_OUTS()
+#endif
+
+#ifdef DEBUG
 static void verify_call_outs(void)
 {
-#ifdef DEBUG
   struct array *v;
-  int e;
+  int e,d;
 
   if(!d_flag) return;
   if(!call_buffer) return;
@@ -78,9 +91,37 @@ static void verify_call_outs(void)
 
     if(v->malloced_size<v->size)
       fatal("Impossible array.\n");
+
+    if(!v->size)
+      fatal("Call out array of zero size!\n");
+
+    if(d_flag>4)
+    {
+      for(d=e+1;d<num_pending_calls;d++)
+	if(CALL(e).args == CALL(d).args)
+	  fatal("Duplicate call out in heap.\n");
+    }
   }
-#endif
+
+  for(d=0;d<10 && e<call_buffer_size;d++,e++)
+  {
+    CALL(e).caller=(struct object *)1; /* Illegal value */
+    CALL(e).args=(struct array *)1; /* Illegal value */
+  }
+}
+
+static struct callback *verify_call_out_callback=0;
+void do_verify_call_outs(struct callback *foo, void *x, void *y)
+{
+  PROTECT_CALL_OUTS();
+  verify_call_outs();
+  UNPROTECT_CALL_OUTS();
 }
+#else
+#define verify_call_outs()
+#endif
+
+
 
 static void adjust_down(int pos)
 {
@@ -156,7 +197,7 @@ static struct array * new_call_out(int num_arg,struct svalue *argp)
     }else{
       new_buffer=(call_out *)realloc((char *)call_buffer, sizeof(call_out)*call_buffer_size*2);
       if(!new_buffer)
-	error("Not enough memorry for another call_out\n");
+	error("Not enough memory for another call_out\n");
       call_buffer_size*=2;
       call_buffer=new_buffer;
     }
@@ -238,8 +279,7 @@ void f_call_out(INT32 args)
   sp[1-args]=tmp;
 
   v=new_call_out(args,sp-args);
-  v->refs++;
-  push_array(v);
+  ref_push_array(v);
 
   /* We do not add this callback until we actually have
    * call outs to take care of.
@@ -249,6 +289,12 @@ void f_call_out(INT32 args)
 
   if(!mem_callback)
     mem_callback=add_memory_usage_callback(count_memory_in_call_outs,0,0);
+
+#ifdef DEBUG
+  if(!verify_call_out_callback)
+    verify_call_out_callback=add_to_callback(& do_debug_callbacks,
+					     do_verify_call_outs, 0, 0);
+#endif
 }
 
 void do_call_outs(struct callback *ignored, void *ignored_too, void *arg)
@@ -266,9 +312,15 @@ void do_call_outs(struct callback *ignored, void *ignored_too, void *arg)
     {
       /* unlink call out */
       call_out c;
+
+      PROTECT_CALL_OUTS();
       c=CALL(0);
-      CALL(0)=CALL(--num_pending_calls);
-      adjust_down(0);
+      if(--num_pending_calls)
+      {
+	CALL(0)=CALL(num_pending_calls);
+	adjust_down(0);
+      }
+      UNPROTECT_CALL_OUTS();
 
       if(c.caller) free_object(c.caller);
 
@@ -337,6 +389,8 @@ void f_find_call_out(INT32 args)
 {
   int e;
   verify_call_outs();
+
+  PROTECT_CALL_OUTS();
   e=find_call_out(sp - args);
   pop_n_elems(args);
   if(e==-1)
@@ -348,6 +402,7 @@ void f_find_call_out(INT32 args)
   }else{
     push_int(CALL(e).tv.tv_sec - current_time.tv_sec);
   }
+  UNPROTECT_CALL_OUTS();
   verify_call_outs();
 }
 
@@ -355,6 +410,7 @@ void f_remove_call_out(INT32 args)
 {
   int e;
   verify_call_outs();
+  PROTECT_CALL_OUTS();
   e=find_call_out(sp-args);
   if(e!=-1)
   {
@@ -376,6 +432,7 @@ void f_remove_call_out(INT32 args)
     sp->u.integer=-1;
     sp++;
   }
+  UNPROTECT_CALL_OUTS();
   verify_call_outs();
 }
 
@@ -388,6 +445,7 @@ struct array *get_all_call_outs(void)
   struct array *ret;
 
   verify_call_outs();
+  PROTECT_CALL_OUTS();
   ret=allocate_array_no_init(num_pending_calls,0);
   for(e=0;e<num_pending_calls;e++)
   {
@@ -413,6 +471,7 @@ struct array *get_all_call_outs(void)
     ITEM(ret)[e].type=T_ARRAY;
     ITEM(ret)[e].u.array=v;
   }
+  UNPROTECT_CALL_OUTS();
   return ret;
 }
 
@@ -436,13 +495,6 @@ void free_all_call_outs(void)
   call_buffer=NULL;
 }
 
-#ifdef DEBUG
-void verify_all_call_outs(void)
-{
-  verify_call_outs();
-}
-#endif
-
 void pike_module_init(void)
 {
   add_efun("call_out",f_call_out,"function(function,float|int,mixed...:mixed)",OPT_SIDE_EFFECT);
diff --git a/src/modules/call_out/test_co.pike b/src/modules/call_out/test_co.pike
index 8403cc15304a93c6b0feb5d768af61ba623d5480..a54907eb47a175f49014375ac8e3792dba4c300d 100644
--- a/src/modules/call_out/test_co.pike
+++ b/src/modules/call_out/test_co.pike
@@ -1,6 +1,6 @@
 #!/usr/local/bin/pike
 
-/* $Id: test_co.pike,v 1.2 1997/05/31 22:04:11 grubba Exp $ */
+/* $Id: test_co.pike,v 1.3 1997/10/23 03:15:42 hubbe Exp $ */
 
 void verify();
 
@@ -10,8 +10,7 @@ int cnt;
 
 #define FUN(X) void X() \
 { \
-  fc[X]--; \
-  if(!(++cnt & 15)) { verify(); werror("."); } \
+  if(!(--fc[X] && (++cnt & 15))) { verify(); werror("."); } \
 }
 
 FUN(f0)
@@ -41,7 +40,8 @@ void verify()
       exit(1);
     }
   }
-  if(!sizeof(ff)) exit(0);
+  if(!sizeof(ff)) { werror("\n"); exit(0); }
+  gc();
 }
 
 mixed co(mixed func, mixed ... args)
@@ -79,8 +79,8 @@ void do_remove()
     verify();
     werror(".");
   }
-  werror("\nWaiting to exit \n");
-  call_out(exit,5,30,1);
+  werror("\nWaiting to exit ");
+  call_out(exit,30,1);
 }
 
 int main()
@@ -115,6 +115,24 @@ int main()
     }
   }
 
+  werror("\nTesting beginning of heap ...");
+
+  verify();
+
+  mixed *tmp=allocate(100);
+  for(int e=0;e<sizeof(tmp);e++) tmp[e]=co(f0,-50.0);
+
+  verify();
+
+  for(int e=0;e<sizeof(tmp);e++)
+  {
+    if(zero_type(rco(tmp[e]))==1)
+    {
+      werror("Remove call out failed!!!\n");
+      exit(1);
+    }
+  }
+
   verify();
   
   werror("\nWaiting ");