diff --git a/src/gc.c b/src/gc.c
index c857796a234b32a2919d93bf845b32f568fc29d9..1e7ae773e7e442783582b9ceccd7bb2cae16ec20 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -51,13 +51,17 @@ struct callback *add_gc_callback(callback_func call,
 }
 
 #define GC_REFERENCED 1
+#define GC_XREFERENCED 2
 
 struct marker
 {
-  struct marker *next;
-  void *marked;
   INT32 refs;
+#ifdef DEBUG
+  INT32 xrefs;
+#endif
   INT32 flags;
+  struct marker *next;
+  void *marked;
 };
 
 struct marker_chunk
@@ -101,6 +105,9 @@ static struct marker *getmark(void *a)
   m=new_marker();
   m->marked=a;
   m->refs=0;
+#ifdef DEBUG
+  m->xrefs=0;
+#endif
   m->flags=0;
   m->next=hash[hashval];
   hash[hashval]=m;
@@ -137,9 +144,13 @@ int gc_is_referenced(void *a)
   struct marker *m;
   m=getmark(a);
 #ifdef DEBUG
-  if(m->refs > *(INT32 *)a)
+  if(m->refs + m->xrefs > *(INT32 *)a)
   {
     check_for=a;
+    fatal("Ref counts are wrong (has %d, found %d + %d external)\n",
+	  *(INT32 *)a,
+	  m->refs,
+	  m->xrefs);
 
     gc_check_all_arrays();
     gc_check_all_multisets();
@@ -155,6 +166,29 @@ int gc_is_referenced(void *a)
   return m->refs < *(INT32 *)a;
 }
 
+#ifdef DEBUG
+int gc_external_mark(void *a)
+{
+  struct marker *m;
+  if(check_for)
+  {
+    if(a==check_for)
+    {
+      gdb_gc_stop_here(a);
+      fprintf(stderr,"--External\n");
+
+      return 1;
+    }
+    return 0;
+  }
+  m=getmark(a);
+  m->xrefs++;
+  m->flags|=GC_XREFERENCED;
+  gc_is_referenced(a);
+  return 0;
+}
+#endif
+
 int gc_mark(void *a)
 {
   struct marker *m;
diff --git a/src/gc.h b/src/gc.h
index e7ee5766691fb558227bd84cca492ededaa3be8f..7f15fd7fe732e41aa1ab02a58a7b9aa3d878c6ab 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -35,6 +35,7 @@ struct marker;
 struct marker_chunk;
 INT32 gc_check(void *a);
 int gc_is_referenced(void *a);
+int gc_external_mark(void *a);
 int gc_mark(void *a);
 int gc_do_free(void *a);
 void do_gc();
diff --git a/src/interpret.c b/src/interpret.c
index 5c6d7a6f3c267d843cb8473afe1ef32da9fc9d9d..34219756a7c1e3a20dca17a671365846de7e4eca 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.42 1997/04/16 03:09:11 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.43 1997/07/19 20:25:24 hubbe Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -84,11 +84,26 @@ int pop_sp_mark()
 
 struct frame *fp; /* frame pointer */
 
+#ifdef DEBUG
+static void gc_check_stack_callback(struct callback *foo, void *bar, void *gazonk)
+{
+  gc_xmark_svalues(evaluator_stack,sp-evaluator_stack-1);
+}
+#endif
+
 void init_interpreter()
 {
 #ifdef USE_MMAP_FOR_STACK
   static int fd = -1;
 
+#ifdef DEBUG
+  static struct callback *spcb;
+  if(!spcb)
+  {
+    spcb=add_gc_callback(gc_check_stack_callback,0,0);
+  }
+#endif
+
 #ifndef MAP_VARIABLE
 #define MAP_VARIABLE 0
 #endif
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 0cb1771971ee9088a27dd38666f1f6104c6e1e01..36a9056b6b3f113c48a8ac903de27d1c142546aa 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -6,7 +6,7 @@
 #define READ_BUFFER 8192
 
 #include "global.h"
-RCSID("$Id: file.c,v 1.48 1997/07/18 01:44:26 hubbe Exp $");
+RCSID("$Id: file.c,v 1.49 1997/07/19 20:25:29 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "stralloc.h"
@@ -1097,10 +1097,15 @@ static void exit_file_struct(struct object *o)
   ERRNO=-1;
 }
 
-static void (struct object *o)
+static void gc_mark_file_struct(struct object *o)
 {
-  FD=-1;
-  ERRNO=-1;
+  if(FD>-1)
+  {
+    gc_mark_svalues(& THIS->read_callback,1);
+    gc_mark_svalues(& THIS->write_callback,1);
+    gc_mark_svalues(& THIS->close_callback,1);
+    gc_mark_svalues(& THIS->id,1);
+  }
 }
 
 static void file_dup(INT32 args)
@@ -1462,6 +1467,10 @@ void mark_ids(struct callback *foo, void *bar, void *gazonk)
       gc_check_svalues( & files[e].read_callback, 1);
       gc_check_svalues( & files[e].close_callback, 1);
     }else{
+#ifdef DEBUG
+      gc_xmark_svalues( & files[e].read_callback, 1);
+      gc_xmark_svalues( & files[e].close_callback, 1);
+#endif
       tmp=0;
     }
 
@@ -1469,6 +1478,9 @@ void mark_ids(struct callback *foo, void *bar, void *gazonk)
     {
       gc_check_svalues( & files[e].write_callback, 1);
     }else{
+#ifdef DEBUG
+      gc_xmark_svalues( & files[e].write_callback, 1);
+#endif
       tmp=0;
     }
 
@@ -1476,6 +1488,12 @@ void mark_ids(struct callback *foo, void *bar, void *gazonk)
     {
       gc_check_svalues( & files[e].id, 1);
     }
+#ifdef DEBUG
+    else
+    {
+      gc_xmark_svalues( & files[e].id, 1);
+    }
+#endif
   }
 }
 
@@ -1534,7 +1552,7 @@ void pike_module_init()
   add_function("open_socket",file_open_socket,"function(int|void,string|void:int)",0);
   add_function("connect",file_connect,"function(string,int:int)",0);
   add_function("query_address",file_query_address,"function(int|void:string)",0);
-  add_function("create",file_create,"function(void|string:void)",0);
+  add_function("create",file_create,"function(void|string,void|string:void)",0);
   add_function("`<<",file_lsh,"function(mixed:object)",0);
 
   set_init_callback(init_file_struct);
diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c
index 0b837cc3c0f07851174fb08276ad0d515db707a8..a75e869a937f7056e6cc51e428951c7a2dedb52c 100644
--- a/src/modules/files/socket.c
+++ b/src/modules/files/socket.c
@@ -55,6 +55,7 @@ struct port
 };
 
 #define THIS ((struct port *)(fp->current_storage))
+static void port_accept_callback(int fd,void *data);
 
 static void do_close(struct port *p, struct object *o)
 {
@@ -371,8 +372,8 @@ void port_setup_program()
   INT32 offset;
   start_new_program();
   offset=add_storage(sizeof(struct port));
-  map_variable("_accept_callback","mixed",offset+OFFSETOF(port,accept_callback),T_MIXED);
-  map_variable("_id","mixed",offset+OFFSETOF(port,id),T_MIXED);
+  map_variable("_accept_callback","mixed",0,offset+OFFSETOF(port,accept_callback),T_MIXED);
+  map_variable("_id","mixed",0,offset+OFFSETOF(port,id),T_MIXED);
   add_function("bind",port_bind,"function(int,void|mixed:int)",0);
   add_function("listen_fd",port_listen_fd,"function(int,void|mixed:int)",0);
   add_function("set_id",port_set_id,"function(mixed:mixed)",0);
diff --git a/src/modules/files/testsuite.in b/src/modules/files/testsuite.in
index 52884e28fe50d45022e2a54d33a55e299aebd553..379e04d2da0377195f9d6399bfbb9b33355e1514 100644
--- a/src/modules/files/testsuite.in
+++ b/src/modules/files/testsuite.in
@@ -1,7 +1,9 @@
 // tests for file module
 test_true(programp(Stdio.File))
 test_true(programp(Stdio.File))
+test_true(objectp(Stdio.File()))
 test_true(programp(Stdio.Port))
+test_true(objectp(Stdio.Port()))
 test_any(object o; o=clone(Stdio.File); destruct(o); return 1,1)
 
 // - file->open
diff --git a/src/program.h b/src/program.h
index 3e59542f3db5ef0c10dc0d4f84b1b250a8fb4a35..10f41ab3e79560b36dc2705e9c454c1c4b4ef070 100644
--- a/src/program.h
+++ b/src/program.h
@@ -200,6 +200,16 @@ void rename_last_inherit(struct pike_string *n);
 void do_inherit(struct program *p,INT32 flags, struct pike_string *name);
 void simple_do_inherit(struct pike_string *s, INT32 flags,struct pike_string *name);
 int isidentifier(struct pike_string *s);
+int low_define_variable(struct pike_string *name,
+			struct pike_string *type,
+			INT32 flags,
+			INT32 offset,
+			INT32 run_time_type);
+int map_variable(char *name,
+		 char *type,
+		 INT32 flags,
+		 INT32 offset,
+		 INT32 run_time_type);
 int define_variable(struct pike_string *name,
 		    struct pike_string *type,
 		    INT32 flags);
diff --git a/src/svalue.c b/src/svalue.c
index 2e34b6270f2b17a3936eae4392b185ec3357d2d8..b261d12f5171d69308b0bcbd59434bef8e239a74 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -899,6 +899,22 @@ TYPE_FIELD gc_check_svalues(struct svalue *s, int num)
   return f;
 }
 
+#ifdef DEBUG
+void gc_xmark_svalues(struct svalue *s, int num)
+{
+  INT32 e;
+
+  for(e=0;e<num;e++,s++)
+  {
+    check_type(s->type);
+    check_refs(s);
+
+    if(s->type <= MAX_REF_TYPE)
+      gc_external_mark(s->u.refs);
+  }
+}
+#endif
+
 void gc_check_short_svalue(union anything *u, TYPE_T type)
 {
   if(!u->refs) return;
diff --git a/src/svalue.h b/src/svalue.h
index 3001f4b165733f1a4234b8059f5e7702b116e56e..5ed08d1b389d14283ce5d958d2fa2484941f1195 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -236,6 +236,7 @@ void copy_svalues_recursively_no_free(struct svalue *to,
 void check_short_svalue(union anything *u,TYPE_T type);
 void check_svalue(struct svalue *s);
 TYPE_FIELD gc_check_svalues(struct svalue *s, int num);
+void gc_xmark_svalues(struct svalue *s, int num);
 void gc_check_short_svalue(union anything *u, TYPE_T type);
 void gc_mark_svalues(struct svalue *s, int num);
 void gc_mark_short_svalue(union anything *u, TYPE_T type);