From 4fab5f45f59af41f8a04567aac6d0455fd16b5b8 Mon Sep 17 00:00:00 2001 From: Martin Stjernholm <mast@lysator.liu.se> Date: Sun, 18 Apr 2004 04:16:06 +0200 Subject: [PATCH] Improved debug during cleanup: If there are internal refs that the gc don't know about it will free them during the leak report. When they then are freed from their real places later on, they will run out of refs. Therefore the debug now prints all locations the leaked objects are freed from. Rev: src/array.h:1.59 Rev: src/dmalloc.h:1.50 Rev: src/gc.c:1.253 Rev: src/gc.h:1.112 Rev: src/main.c:1.200 Rev: src/mapping.h:1.54 Rev: src/multiset.h:1.34 Rev: src/object.h:1.82 Rev: src/program.c:1.563 Rev: src/program.h:1.202 --- src/array.h | 13 +++++++++++-- src/dmalloc.h | 4 +++- src/gc.c | 47 ++++++++++++++++++++++++++++++++++++----------- src/gc.h | 7 +++++-- src/main.c | 12 ++++++++---- src/mapping.h | 13 +++++++++++-- src/multiset.h | 6 +++++- src/object.h | 14 ++++++++++++-- src/program.c | 5 +++-- src/program.h | 13 +++++++++++-- 10 files changed, 105 insertions(+), 29 deletions(-) diff --git a/src/array.h b/src/array.h index ba67be304f..95d54b1b9e 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.58 2004/03/17 15:27:26 grubba Exp $ +|| $Id: array.h,v 1.59 2004/04/18 02:16:05 mast Exp $ */ #ifndef ARRAY_H @@ -68,7 +68,16 @@ extern struct array *gc_internal_array; #define PIKE_ARRAY_OP_SUB PIKE_MINTERM(PIKE_ARRAY_OP_TAKE_A,PIKE_ARRAY_OP_SKIP_A ,PIKE_ARRAY_OP_SKIP_B) -#define free_array(V) do{ struct array *v_=(V); debug_malloc_touch(v_); if(!sub_ref(v_)) really_free_array(v_); }while(0) +#define free_array(V) do{ \ + struct array *v_=(V); \ + debug_malloc_touch(v_); \ + DO_IF_PIKE_CLEANUP ( \ + if (gc_external_refs_zapped) \ + gc_check_zapped (v_, PIKE_T_ARRAY, __FILE__, __LINE__); \ + ); \ + if(!sub_ref(v_)) \ + really_free_array(v_); \ + }while(0) #define allocate_array(X) low_allocate_array((X),0) #define allocate_array_no_init(X,Y) low_allocate_array((X),(Y)) diff --git a/src/dmalloc.h b/src/dmalloc.h index 0149c073f8..ae0260296f 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.49 2004/04/03 18:24:24 mast Exp $ +|| $Id: dmalloc.h,v 1.50 2004/04/18 02:16:05 mast Exp $ */ #ifndef DMALLOC_H @@ -35,6 +35,8 @@ extern size_t dmalloc_tracelogptr; #if defined (PIKE_DEBUG) && defined (DO_PIKE_CLEANUP) extern int verbose_debug_exit; +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 diff --git a/src/gc.c b/src/gc.c index 6f92fe3169..6daa608ae7 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.252 2004/04/17 23:35:53 mast Exp $ +|| $Id: gc.c,v 1.253 2004/04/18 02:16:05 mast Exp $ */ #include "global.h" @@ -33,7 +33,7 @@ struct callback *gc_evaluator_callback=0; #include "block_alloc.h" -RCSID("$Id: gc.c,v 1.252 2004/04/17 23:35:53 mast Exp $"); +RCSID("$Id: gc.c,v 1.253 2004/04/18 02:16:05 mast Exp $"); int gc_enabled = 1; @@ -321,10 +321,11 @@ int attempt_to_identify(void *something, void **inblock) if(safe_debug_findstring((struct pike_string *)something)) return T_STRING; - for (i = 0; i < pike_type_hash_size; i++) - for (t = pike_type_hash[i]; t; t = t->next) - if (t == (struct pike_type *) something) - return T_TYPE; + if (pike_type_hash) + for (i = 0; i < pike_type_hash_size; i++) + for (t = pike_type_hash[i]; t; t = t->next) + if (t == (struct pike_type *) something) + return T_TYPE; for (c = first_callable; c; c = c->next) if (c == (struct callable *) something) @@ -1528,7 +1529,22 @@ static void cleanup_markers (void) { #ifdef DO_PIKE_CLEANUP size_t e=0; - struct marker *h; + + if (gc_keep_markers) { + /* Carry over any GC_CLEANUP_FREED flags but reinitialize them + * otherwise. */ + for(e=0;e<marker_hash_table_size;e++) { + struct marker *m; + for (m = marker_hash_table[e]; m; m = m->next) { + m->flags &= GC_CLEANUP_FREED; + m->refs = m->weak_refs = m->xrefs = 0; + m->saved_refs = -1; + m->frame = 0; + } + } + return; + } + for(e=0;e<marker_hash_table_size;e++) while(marker_hash_table[e]) remove_marker(marker_hash_table[e]->data); @@ -1536,7 +1552,6 @@ static void cleanup_markers (void) exit_marker_hash(); } - static void init_gc(void) { #ifdef PIKE_DEBUG @@ -1544,16 +1559,16 @@ static void init_gc(void) /* 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); + low_init_marker_hash(num_objects); get_marker(rec_list.data); /* Used to simplify fencepost conditions. */ #ifdef PIKE_DEBUG } #endif } -static void exit_gc(void) +void exit_gc(void) { if (gc_evaluator_callback) { remove_callback(gc_evaluator_callback); @@ -1764,6 +1779,16 @@ int gc_mark_external (void *a, const char *place) return 0; } +#ifdef DO_PIKE_CLEANUP +void gc_check_zapped (void *a, TYPE_T type, const char *file, int line) +{ + struct marker *m = find_marker (a); + if (m && (m->flags & GC_CLEANUP_FREED)) + fprintf (stderr, "Free of leaked %s %p from %s:%d, %d refs remaining\n", + get_name_of_type (type), a, file, line, *(INT32 *)a - 1); +} +#endif + void debug_really_free_gc_frame(struct gc_frame *l) { if (l->frameflags & GC_LINK_FREED) diff --git a/src/gc.h b/src/gc.h index f773cf9a82..3c3307e667 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.111 2004/03/19 02:23:26 mast Exp $ +|| $Id: gc.h,v 1.112 2004/04/18 02:16:05 mast Exp $ */ #ifndef GC_H @@ -87,7 +87,6 @@ extern int gc_destruct_everything; #if defined (PIKE_DEBUG) && defined (DO_PIKE_CLEANUP) extern int gc_keep_markers; -extern int gc_external_refs_zapped; #else #define gc_keep_markers 0 #endif @@ -242,6 +241,9 @@ struct marker /* The thing has been visited by gc_checked_as_weak(). */ #define GC_WATCHED 0x01000000 /* The thing has been set under watch by gc_watch(). */ +#define GC_CLEANUP_FREED 0x02000000 +/* The thing was freed by the cleanup code under the assumption that + * references were lost. */ #endif #ifdef PIKE_DEBUG @@ -290,6 +292,7 @@ void gc_watch(void *a); void debug_gc_touch(void *a); PMOD_EXPORT int real_gc_check(void *a); int real_gc_check_weak(void *a); +void exit_gc(void); void locate_references(void *a); void debug_gc_add_extra_ref(void *a); void debug_gc_free_extra_ref(void *a); diff --git a/src/main.c b/src/main.c index e152cf19b9..1b5549bf79 100644 --- a/src/main.c +++ b/src/main.c @@ -2,11 +2,11 @@ || 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.199 2004/04/06 15:37:55 nilsson Exp $ +|| $Id: main.c,v 1.200 2004/04/18 02:16:05 mast Exp $ */ #include "global.h" -RCSID("$Id: main.c,v 1.199 2004/04/06 15:37:55 nilsson Exp $"); +RCSID("$Id: main.c,v 1.200 2004/04/18 02:16:05 mast Exp $"); #include "fdlib.h" #include "backend.h" #include "module.h" @@ -1066,8 +1066,10 @@ void low_exit_main(void) for (i = 0; i < (ptrdiff_t) NELEM (statics); i++) \ if (x == statics[i]) \ is_static = 1; \ - while (x->refs > m->refs + is_static) \ + while (x->refs > m->refs + is_static) { \ + m->flags |= GC_CLEANUP_FREED; \ PIKE_CONCAT(free_, TYPE) (x); \ + } \ } \ } \ } while (0) @@ -1084,9 +1086,11 @@ void low_exit_main(void) * above we should try to handle it gracefully. */ gc_external_refs_zapped = 1; - gc_keep_markers = 0; do_gc (NULL, 1); + gc_keep_markers = 0; + exit_gc(); + #ifdef DEBUG_MALLOC { INT32 num, size; diff --git a/src/mapping.h b/src/mapping.h index c71565e540..2100935504 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.53 2004/03/22 19:35:44 mast Exp $ +|| $Id: mapping.h,v 1.54 2004/04/18 02:16:06 mast Exp $ */ #ifndef MAPPING_H @@ -82,7 +82,16 @@ extern struct mapping *gc_internal_mapping; for(((k = MD_KEYPAIRS((m)->data, (m)->data->hashsize)), e=0) DO_IF_DMALLOC( ?0:(debug_malloc_touch(m),debug_malloc_touch((m)->data)) ) ; e<(m)->data->size; e++,k++) #endif /* PIKE_MAPPING_KEYPAIR_LOOP */ -#define free_mapping(M) do{ struct mapping *m_=(M); debug_malloc_touch(m_); if(!sub_ref(m_)) really_free_mapping(m_); }while(0) +#define free_mapping(M) do{ \ + struct mapping *m_=(M); \ + debug_malloc_touch(m_); \ + DO_IF_PIKE_CLEANUP ( \ + if (gc_external_refs_zapped) \ + gc_check_zapped (m_, PIKE_T_MAPPING, __FILE__, __LINE__); \ + ); \ + if(!sub_ref(m_)) \ + really_free_mapping(m_); \ + }while(0) #define free_mapping_data(M) do{ \ struct mapping_data *md_=(M); \ diff --git a/src/multiset.h b/src/multiset.h index b7c8206834..561f4e5a1b 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.33 2004/04/06 15:37:55 nilsson Exp $ +|| $Id: multiset.h,v 1.34 2004/04/18 02:16:06 mast Exp $ */ #ifndef MULTISET_H @@ -224,6 +224,10 @@ 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 ( \ + if (gc_external_refs_zapped) \ + gc_check_zapped (_ms_, PIKE_T_MULTISET, __FILE__, __LINE__); \ + ); \ if (!sub_ref (_ms_)) really_free_multiset (_ms_); \ } while (0) diff --git a/src/object.h b/src/object.h index e6f97a67f1..d981707107 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.81 2004/03/15 22:47:15 mast Exp $ +|| $Id: object.h,v 1.82 2004/04/18 02:16:06 mast Exp $ */ #ifndef OBJECT_H @@ -38,7 +38,17 @@ extern struct program *magic_set_index_program; extern struct program *magic_indices_program; extern struct program *magic_values_program; -#define free_object(O) do{ struct object *o_=(O); debug_malloc_touch(o_); debug_malloc_touch(o_->storage); if(!sub_ref(o_)) schedule_really_free_object(o_); }while(0) +#define free_object(O) do{ \ + struct object *o_=(O); \ + debug_malloc_touch(o_); \ + debug_malloc_touch(o_->storage); \ + DO_IF_PIKE_CLEANUP ( \ + if (gc_external_refs_zapped) \ + gc_check_zapped (o_, PIKE_T_OBJECT, __FILE__, __LINE__); \ + ); \ + if(!sub_ref(o_)) \ + schedule_really_free_object(o_); \ + }while(0) #ifdef DEBUG_MALLOC #define PIKE_OBJ_STORAGE(O) ((char *)debug_malloc_pass( (O)->storage )) diff --git a/src/program.c b/src/program.c index 618fb671da..e5967e378a 100644 --- a/src/program.c +++ b/src/program.c @@ -2,11 +2,11 @@ || 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.c,v 1.562 2004/04/17 15:18:52 marcus Exp $ +|| $Id: program.c,v 1.563 2004/04/18 02:16:06 mast Exp $ */ #include "global.h" -RCSID("$Id: program.c,v 1.562 2004/04/17 15:18:52 marcus Exp $"); +RCSID("$Id: program.c,v 1.563 2004/04/18 02:16:06 mast Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -2340,6 +2340,7 @@ static void exit_program_struct(struct program *p) #ifdef PIKE_DEBUG if (p->refs) { #ifdef DEBUG_MALLOC + fprintf (stderr, "Program to be freed still got %d references:\n", p->refs); describe_something(p, T_PROGRAM, 0,2,0, NULL); #endif Pike_fatal("Program to be freed still got %d references.\n", p->refs); diff --git a/src/program.h b/src/program.h index 12cdc0f965..fbc0e413af 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.201 2004/03/16 12:46:51 grubba Exp $ +|| $Id: program.h,v 1.202 2004/04/18 02:16:06 mast Exp $ */ #ifndef PROGRAM_H @@ -564,7 +564,16 @@ static inline int CHECK_IDREF_RANGE (int x, const struct program *p) #define FIND_LFUN(P,N) ( dmalloc_touch(struct program *,(P))->flags & PROGRAM_FIXED?((P)->lfuns[(N)]):low_find_lfun((P), (N)) ) #define QUICK_FIND_LFUN(P,N) (dmalloc_touch(struct program *,(P))->lfuns[N]) -#define free_program(p) do{ struct program *_=(p); debug_malloc_touch(_); if(!sub_ref(_)) really_free_program(_); }while(0) +#define free_program(p) do{ \ + struct program *_=(p); \ + debug_malloc_touch(_); \ + DO_IF_PIKE_CLEANUP ( \ + if (gc_external_refs_zapped) \ + gc_check_zapped (_, PIKE_T_PROGRAM, __FILE__, __LINE__); \ + ); \ + if(!sub_ref(_)) \ + really_free_program(_); \ + }while(0) BLOCK_ALLOC_FILL_PAGES(program, n/a) -- GitLab