diff --git a/src/array.h b/src/array.h
index 05140bc9363c438b2c89c72a71709b5a3b31e860..14d75602eb11dcb9b82180da49aa63c19b1d52a5 100644
--- a/src/array.h
+++ b/src/array.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: array.h,v 1.63 2004/09/26 22:07:00 mast Exp $
+|| $Id: array.h,v 1.64 2004/09/27 21:37:22 mast Exp $
 */
 
 #ifndef ARRAY_H
@@ -71,7 +71,7 @@ extern struct array *gc_internal_array;
 #define free_array(V) do{						\
     struct array *v_=(V);						\
     debug_malloc_touch(v_);						\
-    DO_IF_PIKE_CLEANUP (						\
+    DO_IF_DEBUG (							\
       if (gc_external_refs_zapped)					\
 	gc_check_zapped (v_, PIKE_T_ARRAY, __FILE__, __LINE__);		\
     );									\
diff --git a/src/dmalloc.h b/src/dmalloc.h
index 448559be8dbe06df1984b5c5f1f1e9ccd4ca732a..b2f8d116414bc0a97dcc709f3a670677bb69bcd3 100644
--- a/src/dmalloc.h
+++ b/src/dmalloc.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: dmalloc.h,v 1.52 2004/09/26 22:21:17 mast Exp $
+|| $Id: dmalloc.h,v 1.53 2004/09/27 21:37:22 mast Exp $
 */
 
 #ifndef DMALLOC_H
@@ -33,10 +33,13 @@ extern size_t dmalloc_tracelogptr;
 
 #endif /* DMALLOC_TRACE */
 
-#if defined (PIKE_DEBUG) && defined (DO_PIKE_CLEANUP)
-extern int verbose_debug_exit;
+#ifdef PIKE_DEBUG
 extern int gc_external_refs_zapped;
 void gc_check_zapped (void *a, TYPE_T type, const char *file, int line);
+#endif
+
+#ifdef DO_PIKE_CLEANUP
+extern int exit_with_cleanup;
 #define DO_IF_PIKE_CLEANUP(X) X
 #else
 #define DO_IF_PIKE_CLEANUP(X)
diff --git a/src/gc.c b/src/gc.c
index aa9817a26379876bc09394ec456c1b84de7e2cd4..eae1657664d4c10d91ec950c047eed21eadc372d 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: gc.c,v 1.258 2004/09/22 18:08:13 mast Exp $
+|| $Id: gc.c,v 1.259 2004/09/27 21:37:22 mast Exp $
 */
 
 #include "global.h"
@@ -1539,9 +1539,14 @@ static void cleanup_markers (void)
     for(e=0;e<marker_hash_table_size;e++) {
       struct marker *m;
       for (m = marker_hash_table[e]; m; m = m->next) {
+#ifdef PIKE_DEBUG
 	m->flags &= GC_CLEANUP_FREED;
-	m->refs = m->weak_refs = m->xrefs = 0;
+	m->xrefs = 0;
 	m->saved_refs = -1;
+#else
+	m->flags = 0;
+#endif
+	m->refs = m->weak_refs = 0;
 	m->frame = 0;
       }
     }
@@ -1559,12 +1564,14 @@ static void init_gc(void)
 {
 #ifdef PIKE_DEBUG
   if (!gc_is_watching) {
+#endif
+#if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
     /* The marker hash table is left around after a previous gc if
      * gc_keep_markers is set. */
     if (marker_hash_table) cleanup_markers();
     if (!marker_hash_table)
-#endif
       low_init_marker_hash(num_objects);
+#endif
     get_marker(rec_list.data);	/* Used to simplify fencepost conditions. */
 #ifdef PIKE_DEBUG
   }
@@ -1595,7 +1602,7 @@ void exit_gc(void)
 #endif
 }
 
-#ifdef DO_PIKE_CLEANUP
+#ifdef PIKE_DEBUG
 void gc_check_zapped (void *a, TYPE_T type, const char *file, int line)
 {
   struct marker *m = find_marker (a);
diff --git a/src/gc.h b/src/gc.h
index 462a517ca28292704c4dff74e733d175de3c9b39..7103059ca2fd2f83cd5f588bac7d3475281cd086 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: gc.h,v 1.115 2004/06/02 00:07:35 nilsson Exp $
+|| $Id: gc.h,v 1.116 2004/09/27 21:37:23 mast Exp $
 */
 
 #ifndef GC_H
@@ -81,13 +81,9 @@ extern void *gc_svalue_location;
 
 #ifdef DO_PIKE_CLEANUP
 extern int gc_destruct_everything;
-#else
-#define gc_destruct_everything 0
-#endif
-
-#if defined (DO_PIKE_CLEANUP)
 extern int gc_keep_markers;
 #else
+#define gc_destruct_everything 0
 #define gc_keep_markers 0
 #endif
 
diff --git a/src/main.c b/src/main.c
index 1a9da6c61c4b2accf0143fcf84d6f21906b9b759..b6215c895b0ff5cfc14e36c6cf5a11a839d2bda0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: main.c,v 1.209 2004/09/26 15:18:01 marcus Exp $
+|| $Id: main.c,v 1.210 2004/09/27 21:37:23 mast Exp $
 */
 
 #include "global.h"
@@ -928,27 +928,24 @@ void exit_main(void)
 #ifdef DO_PIKE_CLEANUP
   size_t count;
 
-#ifdef PIKE_DEBUG
-  if (verbose_debug_exit)
-    fprintf(stderr,"Exited normally, counting bytes.\n");
-#endif
-
-  /* Destruct all remaining objects while we have a proper execution
-   * environment. The downside is that the leak report below will
-   * always report destructed objects. We use the gc in a special mode
-   * for this to get a reasonably sane destruct order. */
-  gc_destruct_everything = 1;
-  count = do_gc (NULL, 1);
-  while (count) {
-    size_t new_count = do_gc (NULL, 1);
-    if (new_count >= count) {
-      fprintf (stderr, "Some destroy function is creating new objects "
-	       "during final cleanup - can't exit cleanly.\n");
-      break;
+  if (exit_with_cleanup) {
+    /* Destruct all remaining objects while we have a proper execution
+     * environment. The downside is that the leak report below will
+     * always report destructed objects. We use the gc in a special mode
+     * for this to get a reasonably sane destruct order. */
+    gc_destruct_everything = 1;
+    count = do_gc (NULL, 1);
+    while (count) {
+      size_t new_count = do_gc (NULL, 1);
+      if (new_count >= count) {
+	fprintf (stderr, "Some destroy function is creating new objects "
+		 "during final cleanup - can't exit cleanly.\n");
+	break;
+      }
+      count = new_count;
     }
-    count = new_count;
+    gc_destruct_everything = 0;
   }
-  gc_destruct_everything = 0;
 
   /* Unload dynamic modules before static ones. */
   exit_dynamic_load();
@@ -1000,14 +997,15 @@ void low_exit_main(void)
 
   do_gc(NULL, 1);
 
-#ifdef PIKE_DEBUG
-  if(verbose_debug_exit)
+  if (exit_with_cleanup)
   {
+    int leak_found = 0;
+
 #ifdef _REENTRANT
     if(count_pike_threads()>1)
     {
       fprintf(stderr,"Byte counting aborted, because all threads have not exited properly.\n");
-      verbose_debug_exit=0;
+      exit_with_cleanup = 0;
       return;
     }
 #endif
@@ -1026,7 +1024,6 @@ void low_exit_main(void)
 #define STATIC_ARRAYS {&empty_array, &weak_empty_array}
 
 #define REPORT_LINKED_LIST_LEAKS(TYPE, START, STATICS, T_TYPE, NAME) do { \
-      size_t num = 0;							\
       struct TYPE *x;							\
       for (x = START; x; x = x->next) {					\
 	struct marker *m = find_marker (x);				\
@@ -1044,15 +1041,17 @@ void low_exit_main(void)
 	    if (x == statics[i])					\
 	      is_static = 1;						\
 	  if (x->refs != m->refs + is_static) {				\
-	    num++;							\
-	    fprintf (stderr, NAME " got %d unaccounted references:\n",	\
+	    if (!leak_found) {						\
+	      fputs ("Leak(s) found at exit:\n", stderr);		\
+	      leak_found = 1;						\
+	    }								\
+	    fprintf (stderr, NAME " got %d unaccounted references: ",	\
 		     x->refs - (m->refs + is_static));			\
-	    describe_something (x, T_TYPE, 2, 2, 0, NULL);		\
+	    print_short_svalue (stderr, (union anything *) &x, T_TYPE);	\
+	    fputc ('\n', stderr);					\
 	  }								\
 	}								\
       }									\
-      if (num)								\
-	fprintf (stderr, NAME "s left: %"PRINTSIZET"d\n", num);		\
     } while (0)
 
     REPORT_LINKED_LIST_LEAKS (array, first_array, STATIC_ARRAYS, T_ARRAY, "Array");
@@ -1079,7 +1078,7 @@ void low_exit_main(void)
 	    if (x == statics[i])					\
 	      is_static = 1;						\
 	  while (x->refs > m->refs + is_static) {			\
-	    m->flags |= GC_CLEANUP_FREED;				\
+	    DO_IF_DEBUG (m->flags |= GC_CLEANUP_FREED);			\
 	    PIKE_CONCAT(free_, TYPE) (x);				\
 	  }								\
 	}								\
@@ -1094,9 +1093,11 @@ void low_exit_main(void)
 
 #undef ZAP_LINKED_LIST_LEAKS
 
+#ifdef PIKE_DEBUG
     /* If we stumble on the real refs whose refcounts we've zapped
      * above we should try to handle it gracefully. */
     gc_external_refs_zapped = 1;
+#endif
 
     do_gc (NULL, 1);
 
@@ -1113,7 +1114,6 @@ void low_exit_main(void)
     }
 #endif
   }
-#endif
 
   destruct_objects_to_destruct_cb();
 
diff --git a/src/mapping.h b/src/mapping.h
index 84c7a529ded10bd4fc84e87ffa18d2f16cffec96..7fe0d47f10899268352e7dbeadac78f05877332f 100644
--- a/src/mapping.h
+++ b/src/mapping.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: mapping.h,v 1.57 2004/09/26 22:07:00 mast Exp $
+|| $Id: mapping.h,v 1.58 2004/09/27 21:37:23 mast Exp $
 */
 
 #ifndef MAPPING_H
@@ -90,7 +90,7 @@ extern struct mapping *gc_internal_mapping;
 #define free_mapping(M) do{						\
     struct mapping *m_=(M);						\
     debug_malloc_touch(m_);						\
-    DO_IF_PIKE_CLEANUP (						\
+    DO_IF_DEBUG (							\
       if (gc_external_refs_zapped)					\
 	gc_check_zapped (m_, PIKE_T_MAPPING, __FILE__, __LINE__);	\
     );									\
diff --git a/src/multiset.h b/src/multiset.h
index dd611513d7830bf61c320b9edf463269051f63b0..8d3c4d0c48a8567fee192320323ce864b7b6e50b 100644
--- a/src/multiset.h
+++ b/src/multiset.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: multiset.h,v 1.36 2004/09/26 22:07:02 mast Exp $
+|| $Id: multiset.h,v 1.37 2004/09/27 21:37:23 mast Exp $
 */
 
 #ifndef MULTISET_H
@@ -226,7 +226,7 @@ PMOD_PROTO void really_free_multiset (struct multiset *l);
 #define free_multiset(L) do {						\
     struct multiset *_ms_ = (L);					\
     debug_malloc_touch (_ms_);						\
-    DO_IF_PIKE_CLEANUP (						\
+    DO_IF_DEBUG (							\
       if (gc_external_refs_zapped)					\
 	gc_check_zapped (_ms_, PIKE_T_MULTISET, __FILE__, __LINE__);	\
     );									\
diff --git a/src/object.h b/src/object.h
index f768c7a16d9a02707d839329d1fc4f482baee198..a6d5456fa36edd30a2e0f65f244323bf3bb88745 100644
--- a/src/object.h
+++ b/src/object.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: object.h,v 1.86 2004/09/26 22:07:02 mast Exp $
+|| $Id: object.h,v 1.87 2004/09/27 21:37:23 mast Exp $
 */
 
 #ifndef OBJECT_H
@@ -47,7 +47,7 @@ void gc_check_zapped (void *a, TYPE_T type, const char *file, int line);
     struct object *o_=(O);						\
     debug_malloc_touch(o_);						\
     debug_malloc_touch(o_->storage);					\
-    DO_IF_PIKE_CLEANUP (						\
+    DO_IF_DEBUG (							\
       if (gc_external_refs_zapped)					\
 	gc_check_zapped (o_, PIKE_T_OBJECT, __FILE__, __LINE__);	\
     );									\
diff --git a/src/pike_memory.c b/src/pike_memory.c
index 085ecec849032d6a3e4b5cdf0267344f341227a1..c02353d802d88ed6c169068aa9ba1609d25f81bd 100644
--- a/src/pike_memory.c
+++ b/src/pike_memory.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: pike_memory.c,v 1.155 2004/09/18 20:50:53 nilsson Exp $
+|| $Id: pike_memory.c,v 1.156 2004/09/27 21:37:23 mast Exp $
 */
 
 #include "global.h"
@@ -370,8 +370,8 @@ int dmalloc_print_trace;
 #define DMALLOC_TRACE_LOG(X)
 #endif
 
-#if defined (PIKE_DEBUG) && defined (DO_PIKE_CLEANUP)
-int verbose_debug_exit = 1;
+#ifdef DO_PIKE_CLEANUP
+int exit_with_cleanup = 1;
 #endif
 
 #ifdef DEBUG_MALLOC
@@ -2119,7 +2119,7 @@ void cleanup_memhdrs(void)
   }
   exiting=1;
 
-  if(verbose_debug_exit)
+  if (exit_with_cleanup)
   {
     int first=1;
     low_search_all_memheaders_for_references();
diff --git a/src/program.h b/src/program.h
index 6e3774cb068b8bb94aa4b9adb6b59e825e1f52fd..d22f6a446f42d110ee713ca87879cd697184973a 100644
--- a/src/program.h
+++ b/src/program.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: program.h,v 1.209 2004/09/26 22:07:03 mast Exp $
+|| $Id: program.h,v 1.210 2004/09/27 21:37:23 mast Exp $
 */
 
 #ifndef PROGRAM_H
@@ -574,7 +574,7 @@ void gc_check_zapped (void *a, TYPE_T type, const char *file, int line);
 #define free_program(p) do{						\
     struct program *_=(p);						\
     debug_malloc_touch(_);						\
-    DO_IF_PIKE_CLEANUP (						\
+    DO_IF_DEBUG (							\
       if (gc_external_refs_zapped)					\
 	gc_check_zapped (_, PIKE_T_PROGRAM, __FILE__, __LINE__);	\
     );									\
diff --git a/src/stralloc.c b/src/stralloc.c
index 0630566d4c8d0b7f68f542f964a177fba7391263..eff17d269796f7b61054e76535b80b977fe6939c 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: stralloc.c,v 1.167 2004/09/18 22:02:45 nilsson Exp $
+|| $Id: stralloc.c,v 1.168 2004/09/27 21:37:23 mast Exp $
 */
 
 #include "global.h"
@@ -1818,7 +1818,7 @@ void init_shared_string_table(void)
   empty_pike_string = make_shared_string("");
 }
 
-#ifdef DEBUG_MALLOC
+#ifdef DO_PIKE_CLEANUP
 struct shared_string_location *all_shared_string_locations;
 #endif
 
@@ -1833,7 +1833,7 @@ void cleanup_shared_string_table(void)
     empty_pike_string = 0;
   }
 
-#if defined(PIKE_DEBUG) && defined(DEBUG_MALLOC)
+#ifdef DO_PIKE_CLEANUP
   while(all_shared_string_locations)
   {
     struct shared_string_location *x=all_shared_string_locations;
@@ -1842,14 +1842,16 @@ void cleanup_shared_string_table(void)
     x->s=0;
   }
 
-  if(verbose_debug_exit)
+  if (exit_with_cleanup)
   {
     INT32 num,size;
     count_memory_in_strings(&num,&size);
     if(num)
     {
       fprintf(stderr,"Strings left: %d (%d bytes) (zapped)\n",num,size);
+#ifdef PIKE_DEBUG
       dump_stralloc_strings();
+#endif
     }
   }
 #endif
diff --git a/src/stralloc.h b/src/stralloc.h
index 37407d78a7c4f48361f74b385a711fe96b83b3e9..19a6d9bbe8277702e61de8eb6435fea26eb6114d 100644
--- a/src/stralloc.h
+++ b/src/stralloc.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: stralloc.h,v 1.81 2004/04/15 17:34:40 mast Exp $
+|| $Id: stralloc.h,v 1.82 2004/09/27 21:37:23 mast Exp $
 */
 
 #ifndef STRALLOC_H
@@ -103,10 +103,10 @@ static INLINE PCHARP MKPCHARP(void *ptr, int shift)
  MKPCHARP((STR)->str + ((OFF)<<(STR)->size_shift), (STR)->size_shift)
 #define ADD_PCHARP(PTR,I) MKPCHARP_OFF((PTR).ptr,(PTR).shift,(I))
 
+#define reference_shared_string(s) add_ref(s)
+#define copy_shared_string(to,s) add_ref((to)=(s))
 
-#ifdef DEBUG_MALLOC
-#define reference_shared_string(s) do { struct pike_string *S_=(s); add_ref(S_); }while(0)
-#define copy_shared_string(to,s) do { struct pike_string *S_=(to)=(s); add_ref(S_); }while(0)
+#ifdef DO_PIKE_CLEANUP
 
 struct shared_string_location
 {
@@ -128,9 +128,6 @@ extern struct shared_string_location *all_shared_string_locations;
 
 #else
 
-#define reference_shared_string(s) add_ref(s)
-#define copy_shared_string(to,s) add_ref((to)=(s))
-
 #define MAKE_CONST_STRING(var, text)						\
  do { static struct pike_string *str_;                                          \
     if(!str_) str_=make_shared_binary_string((text),CONSTANT_STRLEN(text));     \