diff --git a/src/gc.c b/src/gc.c
index 941e9fe7c141105a671099bf298573770f7d7953..39518ac5de602eb3e8583434f123ef66f0c561c0 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -139,6 +139,8 @@ TYPE_T attempt_to_identify(void *something)
   struct array *a;
   struct object *o;
   struct program *p;
+  struct mapping *m;
+  struct multiset *mu;
 
   a=&empty_array;
   do
@@ -155,6 +157,21 @@ TYPE_T attempt_to_identify(void *something)
     if(p==(struct program *)something)
       return T_PROGRAM;
 
+  for(m=first_mapping;m;m=m->next)
+    if(m==(struct program *)something)
+      return T_MAPPING;
+
+  for(m=first_mapping;m;m=m->next)
+    if(m==(struct mapping *)something)
+      return T_MAPPING;
+
+  for(mu=first_multiset;mu;mu=mu->next)
+    if(mu==(struct multiset *)something)
+      return T_MULTISET;
+
+  if(safe_debug_findstring((struct pike_string *)something))
+    return T_STRING;
+
   return T_UNKNOWN;
 }
 
@@ -168,38 +185,42 @@ void describe_location(void *memblock, TYPE_T type, void *location)
 {
   if(!location) return;
   fprintf(stderr,"**Location of (short) svalue: %p\n",location);
-  if(type==T_OBJECT)
+
+  switch(type)
   {
-    struct object *o=(struct object *)memblock;
-    if(o->prog)
+    case T_OBJECT:
     {
-      INT32 e,d;
-      for(e=0;e<(INT32)o->prog->num_inherits;e++)
+      struct object *o=(struct object *)memblock;
+      if(o->prog)
       {
-	struct inherit tmp=o->prog->inherits[e];
-	char *base=o->storage + tmp.storage_offset;
-
-	for(d=0;d<(INT32)tmp.prog->num_identifiers;d++)
+	INT32 e,d;
+	for(e=0;e<(INT32)o->prog->num_inherits;e++)
 	{
-	  struct identifier *id=tmp.prog->identifiers+d;
-	  if(!IDENTIFIER_IS_VARIABLE(id->identifier_flags)) continue;
-
-	  if(location == (void *)(base + id->func.offset))
+	  struct inherit tmp=o->prog->inherits[e];
+	  char *base=o->storage + tmp.storage_offset;
+	  
+	  for(d=0;d<(INT32)tmp.prog->num_identifiers;d++)
 	  {
-	    fprintf(stderr,"**In variable %s\n",id->name->str);
+	    struct identifier *id=tmp.prog->identifiers+d;
+	    if(!IDENTIFIER_IS_VARIABLE(id->identifier_flags)) continue;
+	    
+	    if(location == (void *)(base + id->func.offset))
+	    {
+	      fprintf(stderr,"**In variable %s\n",id->name->str);
+	    }
 	  }
 	}
       }
+      return;
     }
-    return;
-  }
 
-  if(type == T_ARRAY)
-  {
-    struct array *a=(struct array *)memblock;
-    struct svalue *s=(struct svalue *)location;
-    fprintf(stderr,"**In index %ld\n",(long)(s-ITEM(a)));
-    return;
+    case T_ARRAY:
+    {
+      struct array *a=(struct array *)memblock;
+      struct svalue *s=(struct svalue *)location;
+      fprintf(stderr,"**In index %ld\n",(long)(s-ITEM(a)));
+      return;
+    }
   }
 }
 
@@ -292,6 +313,19 @@ void describe_something(void *a, int t)
       fprintf(stderr,"**Describing array:\n");
       debug_dump_array((struct array *)a);
       break;
+
+    case T_STRING:
+    {
+      struct pike_string *s=(struct pike_string *)a;
+      fprintf(stderr,"**String length is %d:\n",s->len);
+      if(s->len>77)
+      {
+	fprintf(stderr,"** \"%60s ...\"\n",s->str);
+      }else{
+	fprintf(stderr,"** \"%s\"\n",s->str);
+      }
+      break;
+    }
   }
 }
 
diff --git a/src/mapping.h b/src/mapping.h
index 4e50607b52821f7c6d2305272e97b7bd11875cdb..4efb98b5ac8301a0ce01828912fa3aa074cd8dcc 100644
--- a/src/mapping.h
+++ b/src/mapping.h
@@ -17,6 +17,8 @@ struct mapping
   struct keypair *free_list;
 };
 
+extern struct mapping *first_mapping;
+
 #define m_sizeof(m) ((m)->size)
 #define m_ind_types(m) ((m)->ind_types)
 #define m_val_types(m) ((m)->val_types)
diff --git a/src/multiset.h b/src/multiset.h
index 7cc916a59462c4192423c3a88d75a0350d1f62b9..49978ed0a99d14433d38e61f5fe2e8093b043881 100644
--- a/src/multiset.h
+++ b/src/multiset.h
@@ -15,6 +15,8 @@ struct multiset
   struct array *ind;
 };
 
+struct multiset *first_multiset;
+
 #define free_multiset(L) do{ struct multiset *l_=(L); if(!--l_->refs) really_free_multiset(l_); }while(0)
 
 #define l_sizeof(L) ((L)->ind->size)
diff --git a/src/stralloc.c b/src/stralloc.c
index 22e60ca2d400fede9a7c4a63d04f1dda643e5d9d..2ff1752a106cffc76ec023f71c8e1f312193f533 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -329,6 +329,19 @@ void verify_shared_strings_tables(void)
   }
 }
 
+int safe_debug_findstring(struct pike_string *foo)
+{
+  unsigned INT32 e;
+  if(!base_table) return 0;
+  for(e=0;e<htable_size;e++)
+  {
+    struct pike_string *p;
+    for(p=base_table[e];p;p=p->next)
+      if(p==foo) return 1;
+  }
+  return 0;
+}
+
 struct pike_string *debug_findstring(const struct pike_string *foo)
 {
   struct pike_string *tmp;
diff --git a/src/stralloc.h b/src/stralloc.h
index 265a551bed4a54de55110d43118bafd032db65b9..d35dd6265802ebb07fcd4e9147f6176a2c2d5d01 100644
--- a/src/stralloc.h
+++ b/src/stralloc.h
@@ -51,6 +51,7 @@ void really_free_string(struct pike_string *s);
 struct pike_string *add_string_status(int verbose);
 void check_string(struct pike_string *s);
 void verify_shared_strings_tables(void);
+int safe_debug_findstring(struct pike_string *foo);
 struct pike_string *debug_findstring(const struct pike_string *foo);
 void dump_stralloc_strings(void);
 int low_quick_binary_strcmp(char *a,INT32 alen,
@@ -59,6 +60,9 @@ int my_quick_strcmp(struct pike_string *a,struct pike_string *b);
 int my_strcmp(struct pike_string *a,struct pike_string *b);
 struct pike_string *realloc_unlinked_string(struct pike_string *a, INT32 size);
 struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size);
+struct pike_string *modify_shared_string(struct pike_string *a,
+					 INT32 index,
+					 char c);
 struct pike_string *add_shared_strings(struct pike_string *a,
 					 struct pike_string *b);
 struct pike_string *add_and_free_shared_strings(struct pike_string *a,