diff --git a/src/dmalloc.h b/src/dmalloc.h index 15e3c699df64ca2c1a32fba7b693ea40f2ac5127..f22bed7da25058c113025c0594bedc27127b3d78 100644 --- a/src/dmalloc.h +++ b/src/dmalloc.h @@ -1,5 +1,5 @@ /* - * $Id: dmalloc.h,v 1.24 2000/04/08 02:01:08 hubbe Exp $ + * $Id: dmalloc.h,v 1.25 2000/04/15 05:05:28 hubbe Exp $ */ extern char *debug_xalloc(long); @@ -10,7 +10,8 @@ extern char *debug_xalloc(long); struct memhdr; void dump_memhdr_locations(struct memhdr *from, - struct memhdr *notfrom); + struct memhdr *notfrom, + int indent); struct memhdr *alloc_memhdr(void); void really_free_memhdr(struct memhdr *mh); void add_marks_to_memhdr(struct memhdr *to,void *ptr); @@ -53,7 +54,7 @@ char *dmalloc_find_name(void *p); #define debug_malloc_touch(X) debug_malloc_update_location((X),DMALLOC_LOCATION()) #define debug_malloc_pass(X) debug_malloc_update_location((X),DMALLOC_LOCATION()) #define xalloc(X) ((char *)debug_malloc_pass(debug_xalloc(X))) -void debug_malloc_dump_references(void *x); +void debug_malloc_dump_references(void *x, int indent, int depth, int flags); #define dmalloc_touch(TYPE,X) ((TYPE)debug_malloc_update_location((X),DMALLOC_LOCATION())) #define dmalloc_touch_svalue(X) do { struct svalue *_tmp = (X); if ((X)->type <= MAX_REF_TYPE) { debug_malloc_touch(_tmp->u.refs); } } while(0) @@ -70,7 +71,7 @@ struct memory_map; void dmalloc_set_mmap(void *ptr, struct memory_map *m); void dmalloc_set_mmap_template(void *ptr, struct memory_map *m); void dmalloc_set_mmap_from_template(void *p, void *p2); -void dmalloc_describe_location(void *p, int offset); +void dmalloc_describe_location(void *p, int offset, int indent); struct memory_map *dmalloc_alloc_mmap(char *name, int line); void dmalloc_add_mmap_entry(struct memory_map *m, char *name, @@ -90,7 +91,7 @@ void dmalloc_add_mmap_entry(struct memory_map *m, #define DMALLOC_LINE_ARGS #define DMALLOC_POS #define DMALLOC_PROXY_ARGS -#define debug_malloc_dump_references(X) +#define debug_malloc_dump_references(X,x,y,z) #define xalloc debug_xalloc #define dbm_main main #define DO_IF_DMALLOC(X) diff --git a/src/gc.c b/src/gc.c index ac625937e73b35c97766d7841bc4fff183663b28..b5c73ad5b1e8cdac47b938f1e12e079ec7a4064e 100644 --- a/src/gc.c +++ b/src/gc.c @@ -29,7 +29,7 @@ struct callback *gc_evaluator_callback=0; #include "block_alloc.h" -RCSID("$Id: gc.c,v 1.64 2000/04/15 01:04:01 mast Exp $"); +RCSID("$Id: gc.c,v 1.65 2000/04/15 05:05:28 hubbe Exp $"); /* Run garbage collect approximate every time we have * 20 percent of all arrays, objects and programs is @@ -128,18 +128,31 @@ static char *found_where=""; static void *found_in=0; static int found_in_type=0; void *gc_svalue_location=0; - -#ifdef PIKE_DEBUG static char *fatal_after_gc=0; -#endif +#define DESCRIBE_MEM 1 +#define DESCRIBE_NO_REFS 2 +#define DESCRIBE_SHORT 4 +#define DESCRIBE_NO_DMALLOC 8 -void describe_location(void *memblock, int type, void *location) +/* type == -1 means that memblock is a char* and should be + * really be printed.. + */ +void describe_location(void *real_memblock, + int real_type, + void *location, + int indent, + int depth, + int flags) { struct program *p; + void *memblock=0; + int type=real_type; if(!location) return; /* fprintf(stderr,"**Location of (short) svalue: %p\n",location); */ + if(real_type!=-1) real_memblock=memblock; + #ifdef DEBUG_MALLOC if(memblock == 0 || type == -1) { @@ -148,20 +161,25 @@ void describe_location(void *memblock, int type, void *location) } #endif - if(type==T_UNKNOWN) type=attempt_to_identify(memblock); + if(type==T_UNKNOWN) + type=attempt_to_identify(memblock); if(memblock) - fprintf(stderr," <from %s %p offset %ld>\n", + fprintf(stderr,"%*s-> from %s %p offset %ld\n", + indent,"", get_name_of_type(type), memblock, ((long)location - (long)memblock)); else - fprintf(stderr," <at location %p in unknown memblock (mmaped?)>\n", + fprintf(stderr,"%*s-> at location %p in unknown memblock (mmaped?)\n", + indent,"", location); - if(memblock) describe_something(memblock,type,1); + if(memblock && depth>0) + describe_something(memblock,type,indent+2,depth-1,flags | DESCRIBE_MEM); + again: switch(type) { case T_UNKNOWN: @@ -169,59 +187,66 @@ void describe_location(void *memblock, int type, void *location) { if(memblock == (void *)p->program) { - fprintf(stderr," **In memory block for program at %p\n",p); + fprintf(stderr,"%*s **In memory block for program at %p\n", + indent,"", + p); memblock=p; type=T_PROGRAM; - goto describe_program_location; + goto again; } } break; case T_PROGRAM: - describe_program_location: { long e; - struct program *p=(struct program *)memblock; char *ptr=(char *)location; + p=(struct program *)memblock; if(location == (void *)&p->prev) - fprintf(stderr," **In p->prev\n"); + fprintf(stderr,"%*s **In p->prev\n",indent,""); if(location == (void *)&p->next) - fprintf(stderr," **In p->next\n"); + fprintf(stderr,"%*s **In p->next\n",indent,""); - if(ptr >= (char *)p->inherits && ptr<(char*)(p->inherits+p->num_inherits)) + if(p->inherits && + ptr >= (char *)p->inherits && + ptr<(char*)(p->inherits+p->num_inherits)) { e=((long)ptr - (long)(p->inherits)) / sizeof(struct inherit); - fprintf(stderr," **In p->inherits[%ld] (%s)\n", + fprintf(stderr,"%*s **In p->inherits[%ld] (%s)\n",indent,"", e, p->inherits[e].name ? p->inherits[e].name->str : "no name"); return; } - if(ptr >= (char *)p->constants && ptr<(char*)(p->constants+p->num_constants)) + if(p->constants && + ptr >= (char *)p->constants && + ptr<(char*)(p->constants+p->num_constants)) { e=((long)ptr - (long)(p->constants)) / sizeof(struct program_constant); - fprintf(stderr," **In p->constants[%ld] (%s)\n", + fprintf(stderr,"%*s **In p->constants[%ld] (%s)\n",indent,"", e, p->constants[e].name ? p->constants[e].name->str : "no name"); return; } - if(ptr >= (char *)p->identifiers && ptr<(char*)(p->identifiers+p->num_identifiers)) + if(p->identifiers && + ptr >= (char *)p->identifiers && + ptr<(char*)(p->identifiers+p->num_identifiers)) { e=((long)ptr - (long)(p->identifiers)) / sizeof(struct identifier); - fprintf(stderr," **In p->identifiers[%ld] (%s)\n", + fprintf(stderr,"%*s **In p->identifiers[%ld] (%s)\n",indent,"", e, - p->identifiers[e].name ? p->constants[e].name->str : "no name"); + p->identifiers[e].name ? p->identifiers[e].name->str : "no name"); return; } #define FOO(NTYP,TYP,NAME) \ - if(location == (void *)&p->NAME) fprintf(stderr," **In p->" #NAME "\n"); \ + if(location == (void *)&p->NAME) fprintf(stderr,"%*s **In p->" #NAME "\n",indent,""); \ if(ptr >= (char *)p->NAME && ptr<(char*)(p->NAME+p->PIKE_CONCAT(num_,NAME))) \ - fprintf(stderr," **In p->" #NAME "[%ld]\n",((long)ptr - (long)(p->NAME)) / sizeof(TYP)); + fprintf(stderr,"%*s **In p->" #NAME "[%ld]\n",indent,"",((long)ptr - (long)(p->NAME)) / sizeof(TYP)); #include "program_areas.h" return; @@ -232,10 +257,10 @@ void describe_location(void *memblock, int type, void *location) struct object *o=(struct object *)memblock; struct program *p; - if(location == (void *)&o->parent) fprintf(stderr," **In o->parent\n"); - if(location == (void *)&o->prog) fprintf(stderr," **In o->prog\n"); - if(location == (void *)&o->next) fprintf(stderr," **In o->next\n"); - if(location == (void *)&o->prev) fprintf(stderr," **In o->prev\n"); + if(location == (void *)&o->parent) fprintf(stderr,"%*s **In o->parent\n",indent,""); + if(location == (void *)&o->prog) fprintf(stderr,"%*s **In o->prog\n",indent,""); + if(location == (void *)&o->next) fprintf(stderr,"%*s **In o->next\n",indent,""); + if(location == (void *)&o->prev) fprintf(stderr,"%*s **In o->prev\n",indent,""); p=o->prog; @@ -243,7 +268,7 @@ void describe_location(void *memblock, int type, void *location) { p=id_to_program(o->program_id); if(p) - fprintf(stderr," **(We are lucky, found program for destructed object)\n"); + fprintf(stderr,"%*s **(We are lucky, found program for destructed object)\n",indent,""); } if(p) @@ -261,14 +286,14 @@ void describe_location(void *memblock, int type, void *location) if(location == (void *)(base + id->func.offset)) { - fprintf(stderr," **In variable %s\n",id->name->str); + fprintf(stderr,"%*s **In variable %s\n",indent,"",id->name->str); } } if((char *)location >= base && (char *)location <= base + ( tmp.prog->storage_needed - tmp.prog->inherits[0].storage_offset )) { - fprintf(stderr," **In storage for inherit %d",e); + fprintf(stderr,"%*s **In storage for inherit %d",indent,"",e); if(tmp.name) fprintf(stderr," (%s)",tmp.name->str); fprintf(stderr,"\n"); @@ -283,7 +308,7 @@ void describe_location(void *memblock, int type, void *location) { struct array *a=(struct array *)memblock; struct svalue *s=(struct svalue *)location; - fprintf(stderr," **In index %ld\n",(long)(s-ITEM(a))); + fprintf(stderr,"%*s **In index %ld\n",indent,"",(long)(s-ITEM(a))); return; } } @@ -292,8 +317,8 @@ void describe_location(void *memblock, int type, void *location) static void gdb_gc_stop_here(void *a) { fprintf(stderr,"***One ref found%s.\n",found_where?found_where:""); - describe_something(found_in, found_in_type, 0); - describe_location(found_in , found_in_type, gc_svalue_location); + describe_something(found_in, found_in_type, 2, 1, DESCRIBE_NO_DMALLOC); + describe_location(found_in , found_in_type, gc_svalue_location,2,1,0); fprintf(stderr,"----------end------------\n"); } @@ -338,39 +363,47 @@ int debug_gc_check(void *x, TYPE_T t, void *data) return ret; } -void low_describe_something(void *a, int t, int dm) +void low_describe_something(void *a, + int t, + int indent, + int depth, + int flags) { struct program *p=(struct program *)a; + if(depth<0) return; + switch(t) { case T_FUNCTION: if(attempt_to_identify(a) != T_OBJECT) { - fprintf(stderr,"**Builtin function!\n"); + fprintf(stderr,"%*s**Builtin function!\n",indent,""); break; } case T_OBJECT: p=((struct object *)a)->prog; - fprintf(stderr,"**Parent identifier: %d\n",((struct object *)a)->parent_identifier); - fprintf(stderr,"**Program id: %ld\n",((struct object *)a)->program_id); + fprintf(stderr,"%*s**Parent identifier: %d\n",indent,"",((struct object *)a)->parent_identifier); + fprintf(stderr,"%*s**Program id: %ld\n",indent,"",((struct object *)a)->program_id); if( ((struct object *)a)->parent) { - fprintf(stderr,"**Describing object's parent:\n"); - describe_something( ((struct object *)a)->parent, t, 1); + fprintf(stderr,"%*s**Describing object's parent:\n",indent,""); + describe_something( ((struct object *)a)->parent, t, indent+2,depth-1, + (flags | DESCRIBE_SHORT | DESCRIBE_NO_REFS ) + & ~ (DESCRIBE_MEM)); }else{ - fprintf(stderr,"**There is no parent (any longer?)\n"); + fprintf(stderr,"%*s**There is no parent (any longer?)\n",indent,""); } if(!p) { - fprintf(stderr,"**The object is destructed.\n"); + fprintf(stderr,"%*s**The object is destructed.\n",indent,""); p=id_to_program(((struct object *)a)->program_id); if(!p) break; } - fprintf(stderr,"**Attempting to describe program object was instantiated from:\n"); + fprintf(stderr,"%*s**Attempting to describe program object was instantiated from:\n",indent,""); case T_PROGRAM: { @@ -378,17 +411,17 @@ void low_describe_something(void *a, int t, int dm) INT32 line,pos; int foo=0; - fprintf(stderr,"**Program id: %ld\n",(long)(p->id)); + fprintf(stderr,"%*s**Program id: %ld\n",indent,"",(long)(p->id)); if(p->flags & PROGRAM_HAS_C_METHODS) { - fprintf(stderr,"**The program was written in C.\n"); + fprintf(stderr,"%*s**The program was written in C.\n",indent,""); } for(pos=0;pos<100;pos++) { tmp=get_line(p->program+pos, p, &line); if(tmp && line) { - fprintf(stderr,"**Location: %s:%ld\n",tmp,(long)line); + fprintf(stderr,"%*s**Location: %s:%ld\n",indent,"",tmp,(long)line); foo=1; break; } @@ -398,7 +431,7 @@ void low_describe_something(void *a, int t, int dm) #if 0 if(!foo && p->num_linenumbers>1 && EXTRACT_UCHAR(p->linenumbers)=='\177') { - fprintf(stderr,"**From file: %s\n",p->linenumbers+1); + fprintf(stderr,"%*s**From file: %s\n",indent,"",p->linenumbers+1); foo=1; } #endif @@ -406,93 +439,90 @@ void low_describe_something(void *a, int t, int dm) if(!foo) { int e; -#if 0 - fprintf(stderr,"**identifiers:\n"); - for(e=0;e<p->num_identifiers;e++) - fprintf(stderr,"**** %s\n",p->identifiers[e].name->str); -#else - fprintf(stderr,"**identifiers:\n"); + fprintf(stderr,"%*s**identifiers:\n",indent,""); for(e=0;e<p->num_identifier_references;e++) - fprintf(stderr,"**** %s\n",ID_FROM_INT(p,e)->name->str); + fprintf(stderr,"%*s**** %s\n",indent,"",ID_FROM_INT(p,e)->name->str); -#endif - - fprintf(stderr,"**num inherits: %d\n",p->num_inherits); + fprintf(stderr,"%*s**num inherits: %d\n",indent,"",p->num_inherits); } + + if(flags & DESCRIBE_MEM) + { #define FOO(NUMTYPE,TYPE,NAME) \ - fprintf(stderr,"* " #NAME " %p[%d]\n",p->NAME,p->PIKE_CONCAT(num_,NAME)); + fprintf(stderr,"%*s* " #NAME " %p[%d]\n",indent,"",p->NAME,p->PIKE_CONCAT(num_,NAME)); #include "program_areas.h" + } break; } case T_ARRAY: - fprintf(stderr,"**Describing array:\n"); + fprintf(stderr,"%*s**Describing array:\n",indent,""); debug_dump_array((struct array *)a); break; case T_MAPPING: - fprintf(stderr,"**Describing mapping:\n"); + fprintf(stderr,"%*s**Describing mapping:\n",indent,""); debug_dump_mapping((struct mapping *)a); - fprintf(stderr,"**Describing mapping data block:\n"); - describe_something( ((struct mapping *)a)->data, -2, dm); + fprintf(stderr,"%*s**Describing mapping data block:\n",indent,""); + describe_something( ((struct mapping *)a)->data, -2, indent+2,depth-1,flags); break; case T_STRING: { struct pike_string *s=(struct pike_string *)a; - fprintf(stderr,"**String length is %d:\n",s->len); + fprintf(stderr,"%*s**String length is %d:\n",indent,"",s->len); if(s->len>77) { - fprintf(stderr,"** \"%60s ...\"\n",s->str); + fprintf(stderr,"%*s** \"%60s ...\"\n",indent,"",s->str); }else{ - fprintf(stderr,"** \"%s\"\n",s->str); + fprintf(stderr,"%*s** \"%s\"\n",indent,"",s->str); } break; } } } -void describe_something(void *a, int t, int dm) +void describe_something(void *a, int t, int indent, int depth, int flags) { struct program *p=(struct program *)a; if(!a) return; if(t==-1) { - fprintf(stderr,"**Location description: %s\n",(char *)a); + fprintf(stderr,"%*s**Location description: %s\n",indent,"",(char *)a); return; } #ifdef DEBUG_MALLOC if (((int)a) == 0x55555555) { - fprintf(stderr,"**Location: %p Type: %s Zapped pointer\n",a, + fprintf(stderr,"%*s**Location: %p Type: %s Zapped pointer\n",indent,"",a, get_name_of_type(t)); } else #endif /* DEBUG_MALLOC */ if (((int)a) & 3) { - fprintf(stderr,"**Location: %p Type: %s Missaligned address\n",a, + fprintf(stderr,"%*s**Location: %p Type: %s Missaligned address\n",indent,"",a, get_name_of_type(t)); } else { - fprintf(stderr,"**Location: %p Type: %s Refs: %d\n",a, + fprintf(stderr,"%*s**Location: %p Type: %s Refs: %d\n",indent,"",a, get_name_of_type(t), *(INT32 *)a); } - low_describe_something(a,t,dm); + low_describe_something(a,t,indent,depth,flags); #ifdef DEBUG_MALLOC - if(dm) - debug_malloc_dump_references(a); + if(!(flags & DESCRIBE_NO_DMALLOC)) + debug_malloc_dump_references(a,indent+2,depth-1,flags); #endif - fprintf(stderr,"*******************\n"); + fprintf(stderr,"%*s*******************\n",indent,""); } void describe(void *x) { - describe_something(x, attempt_to_identify(x),1); + describe_something(x, attempt_to_identify(x), 0, 2, 0); } void debug_describe_svalue(struct svalue *s) @@ -527,7 +557,7 @@ void debug_describe_svalue(struct svalue *s) } } } - describe_something(s->u.refs,s->type,1); + describe_something(s->u.refs,s->type,0,2,0); } #endif @@ -684,7 +714,7 @@ int debug_gc_is_referenced(void *a) d_flag=0; fprintf(stderr,"**Something has %ld references, while gc() found %ld + %ld external.\n",(long)*(INT32 *)a,(long)refs,(long)xrefs); - describe_something(a, t, 1); + describe_something(a, t, 0,2,0); locate_references(a); @@ -728,7 +758,7 @@ int gc_external_mark3(void *a, void *in, char *where) { fprintf(stderr,"EXTERNAL Reference to object to free%s!\n",in?(char *)in:""); fprintf(stderr," has %ld references, while gc() found %ld + %ld external.\n",(long)*(INT32 *)a,(long)m->refs,(long)m->xrefs); - if(where) describe_location(0,T_UNKNOWN,where); + if(where) describe_location(0,T_UNKNOWN,where,4,1,0); describe(a); locate_references(a); fprintf(stderr,"##### Continuing search for more bugs....\n"); @@ -779,7 +809,7 @@ int debug_gc_do_free(void *a) "**gc_is_referenced failed, object has %ld references,\n" "** while gc() found %ld + %ld external. (type=%d, flags=%d)\n", (long)*(INT32 *)a,(long)refs,(long)xrefs,t,m->flags); - describe_something(a, t, 1); + describe_something(a, t, 4,1,0); locate_references(a); @@ -799,6 +829,7 @@ void do_gc(void) double tmp; INT32 tmp2; double multiplier; +#ifdef HAVE_GETHRTIME #ifdef PIKE_DEBUG #ifdef HAVE_GETHRTIME hrtime_t gcstarttime; @@ -897,6 +928,7 @@ void do_gc(void) exit_gc(); + Pike_in_gc=5; destruct_objects_to_destruct(); objects_freed -= (double) num_objects; @@ -919,14 +951,16 @@ void do_gc(void) #ifdef PIKE_DEBUG if(t_flag) + { +#ifdef HAVE_GETHRTIME fprintf(stderr,"done (freed %ld of %ld objects), %ld ms.\n", (long)(tmp2-num_objects),(long)tmp2, -#ifdef HAVE_GETHRTIME - (long)((gethrtime() - gcstarttime)/1000000) + (long)((gethrtime() - gcstarttime)/1000000)); #else - 0l + fprintf(stderr,"done (freed %ld of %ld objects)\n", + (long)(tmp2-num_objects),(long)tmp2); #endif - ); + } #endif #ifdef ALWAYS_GC diff --git a/src/gc.h b/src/gc.h index 1015f01417c56bcfe73e6f80aa77cbd8bc81887b..76fd020560905eedb49e8a908ecee311ffa719c5 100644 --- a/src/gc.h +++ b/src/gc.h @@ -1,5 +1,5 @@ /* - * $Id: gc.h,v 1.28 2000/04/14 16:05:27 mast Exp $ + * $Id: gc.h,v 1.29 2000/04/15 05:05:28 hubbe Exp $ */ #ifndef GC_H #define GC_H @@ -48,12 +48,12 @@ struct callback *debug_add_gc_callback(callback_func call, callback_func free_func); void dump_gc_info(void); TYPE_T attempt_to_identify(void *something); -void describe_location(void *memblock, int type, void *location); +void describe_location(void *memblock, int type, void *location,int indent, int depth, int flags); void debug_gc_xmark_svalues(struct svalue *s, int num, char *fromwhere); TYPE_FIELD debug_gc_check_svalues(struct svalue *s, int num, TYPE_T t, void *data); void debug_gc_check_short_svalue(union anything *u, TYPE_T type, TYPE_T t, void *data); int debug_gc_check(void *x, TYPE_T t, void *data); -void describe_something(void *a, int t, int dm); +void describe_something(void *a, int t, int indent, int depth, int flags); void describe(void *x); void debug_describe_svalue(struct svalue *s); INT32 real_gc_check(void *a); diff --git a/src/interpreter.h b/src/interpreter.h index 436ff8462a5010bc4fa7d735bb56a24894b73df1..6b39a9fb644c989a996243f806ded3f10bb7d085 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -276,7 +276,7 @@ static int eval_instruction(unsigned char *pc) #ifdef DEBUG_MALLOC if (inherit->storage_offset == 0x55555555) { fprintf(stderr, "The inherit %p has been zapped!\n", inherit); - debug_malloc_dump_references(inherit); + debug_malloc_dump_references(inherit,0,2,0); fprintf(stderr, "It was extracted from the program %p %d\n", p, i); describe(p); fprintf(stderr, "Which was in turn taken from the object %p\n", o); diff --git a/src/las.c b/src/las.c index a726973154cc18f3f41e77ffc4581991384ea842..dfc198978c28f763e630039ab56c1e6c14dd9bbd 100644 --- a/src/las.c +++ b/src/las.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: las.c,v 1.174 2000/04/06 09:03:59 hubbe Exp $"); +RCSID("$Id: las.c,v 1.175 2000/04/15 05:05:28 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -380,7 +380,7 @@ void free_all_nodes(void) tmp, tmp->current_file->str, tmp->line_number, tmp->token); - debug_malloc_dump_references(tmp); + debug_malloc_dump_references(tmp,0,2,0); if(tmp->token==F_CONSTANT) print_tree(tmp); diff --git a/src/main.c b/src/main.c index 92ebcccdd423dd7ecf6ea473af93d80671443463..a71390ef52ae8122cfdbe858077047a7718c1102 100644 --- a/src/main.c +++ b/src/main.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: main.c,v 1.88 2000/04/08 01:09:56 hubbe Exp $"); +RCSID("$Id: main.c,v 1.89 2000/04/15 05:05:28 hubbe Exp $"); #include "fdlib.h" #include "backend.h" #include "module.h" @@ -676,7 +676,7 @@ void low_exit_main(void) { struct program *p; for(p=first_program;p;p=p->next) - describe_something(p, T_PROGRAM, 1); + describe_something(p, T_PROGRAM, 0,2,0); } @@ -687,7 +687,7 @@ void low_exit_main(void) { struct object *o; for(o=first_object;o;o=o->next) - describe_something(o, T_OBJECT, 1); + describe_something(o, T_OBJECT, 0,2,0); } cleanup_shared_string_table(); diff --git a/src/mapping.c b/src/mapping.c index fd19c3f43727f12d5b02550f7405ee78e998bd07..fe77bad5d161e6715e574a40e1991cea0696c37d 100644 --- a/src/mapping.c +++ b/src/mapping.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: mapping.c,v 1.72 2000/04/12 18:40:12 hubbe Exp $"); +RCSID("$Id: mapping.c,v 1.73 2000/04/15 05:05:28 hubbe Exp $"); #include "main.h" #include "object.h" #include "mapping.h" @@ -1707,7 +1707,13 @@ void check_mapping(struct mapping *m) fatal("Mapping ->next->prev != mapping.\n"); if(m->debug_size != md->size) - fatal("Mapping zapping detected!\n"); + { + fprintf(stderr,"--MAPPING ZAPPING, mapping:\n"); + describe(m); + fprintf(stderr,"--MAPPING ZAPPING, mapping data:\n"); + describe(md); + fatal("Mapping zapping detected (%d != %d)!\n",m->debug_size,md->size); + } if(m->prev) { @@ -1858,7 +1864,7 @@ void gc_check_all_mappings(void) #ifdef DEBUG_MALLOC if (((int)m->data) == 0x55555555) { fprintf(stderr, "** Zapped mapping in list of active mappings!\n"); - describe_something(m, T_MAPPING, 1); + describe_something(m, T_MAPPING, 0,2,0); fatal("Zapped mapping in list of active mappings!\n"); } #endif /* DEBUG_MALLOC */ diff --git a/src/object.c b/src/object.c index 09085831228317532d2e0ba1bfe467f0a0741a84..af08e577665adbba1e677f178baa32ad6e8425c7 100644 --- a/src/object.c +++ b/src/object.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: object.c,v 1.108 2000/04/14 19:35:29 grubba Exp $"); +RCSID("$Id: object.c,v 1.109 2000/04/15 05:05:28 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -115,11 +115,8 @@ struct object *low_clone(struct program *p) add_ref(p); o->parent=0; o->parent_identifier=0; - o->next=first_object; - o->prev=0; - if(first_object) - first_object->prev=o; - first_object=o; + + DOUBLELINK(first_object,o); o->refs=1; #ifdef PIKE_DEBUG @@ -541,29 +538,25 @@ static struct callback *destruct_object_evaluator_callback =0; */ void destruct_objects_to_destruct(void) { + struct object *my_list=0; struct object *o, *next; while((o=objects_to_destruct)) { -#ifdef PIKE_DEBUG - if(o->refs) - fatal("Object to be destructed grew extra references.\n"); -#endif /* Link object back to list of objects */ - objects_to_destruct=o->next; + DOUBLEUNLINK(objects_to_destruct,o); - if(first_object) - first_object->prev=o; - - o->next=first_object; - first_object=o; - o->prev=0; - + /* link */ + DOUBLELINK(first_object,o); + + /* call destroy, keep one ref */ add_ref(o); + call_destroy(o,0); + destruct(o); free_object(o); } - objects_to_destruct=0; + if(destruct_object_evaluator_callback) { remove_callback(destruct_object_evaluator_callback); @@ -572,7 +565,7 @@ void destruct_objects_to_destruct(void) } -/* really_free_objects: +/* really_free_object: * This function is called when an object runs out of references. * It frees the object if it is destructed, otherwise it moves it to * a separate list of objects which will be destructed later. @@ -580,6 +573,7 @@ void destruct_objects_to_destruct(void) void really_free_object(struct object *o) { + debug_malloc_touch(o); if(o->prog && (o->prog->flags & PROGRAM_DESTRUCT_IMMEDIATE)) { add_ref(o); @@ -587,12 +581,9 @@ void really_free_object(struct object *o) if(--o->refs > 0) return; } - if(o->prev) - o->prev->next=o->next; - else - first_object=o->next; + debug_malloc_touch(o); - if(o->next) o->next->prev=o->prev; + DOUBLEUNLINK(first_object,o); if(o->prog) { @@ -603,9 +594,8 @@ void really_free_object(struct object *o) (callback_func)destruct_objects_to_destruct, 0,0); } - o->next=objects_to_destruct; - o->prev=0; - objects_to_destruct=o; + + DOUBLELINK(objects_to_destruct,o); } else { if(o->parent) { @@ -1002,7 +992,11 @@ void cleanup_objects(void) { add_ref(o); if(o->prog && !(o->prog->flags & PROGRAM_NO_EXPLICIT_DESTRUCT)) + { + debug_malloc_touch(o); + call_destroy(o,1); low_destruct(o,1); + } SET_NEXT_AND_FREE(o,free_object); } free_object(master_object); @@ -1214,6 +1208,7 @@ void gc_mark_all_objects(void) void gc_free_all_unreferenced_objects(void) { struct object *o,*next; + extern int Pike_in_gc; #ifdef PIKE_DEBUG if(d_flag) @@ -1232,15 +1227,15 @@ void gc_free_all_unreferenced_objects(void) } #endif + Pike_in_gc=4; /* Allow thread switches, god help us */ + for(o=first_object;o;o=next) { + next=o->next; if(gc_do_free(o)) { add_ref(o); call_destroy(o,0); - SET_NEXT_AND_FREE(o,free_object); - }else{ - next=o->next; } } @@ -1248,8 +1243,7 @@ void gc_free_all_unreferenced_objects(void) { if(gc_do_free(o)) { - add_ref(o); - destruct(o); + low_destruct(o,1); SET_NEXT_AND_FREE(o,free_object); }else{ next=o->next; @@ -1481,12 +1475,18 @@ void check_object(struct object *o) if(o == fake_object) return; if(o->next && o->next->prev !=o) + { + describe(o); fatal("Object check: o->next->prev != o\n"); + } if(o->prev) { if(o->prev->next != o) + { + describe(o); fatal("Object check: o->prev->next != o\n"); + } if(o == first_object) fatal("Object check: o->prev !=0 && first_object == o\n"); @@ -1522,9 +1522,11 @@ void check_all_objects(void) SET_NEXT_AND_FREE(o,free_object); } +#if 0 for(o=objects_to_destruct;o;o=o->next) if(o->refs) fatal("Object to be destructed has references.\n"); +#endif } diff --git a/src/pike_macros.h b/src/pike_macros.h index 997b6a2da858c943f67c6c09d4a98e585beabc64..1382101461439f90b97d255aed1af4c780954918 100644 --- a/src/pike_macros.h +++ b/src/pike_macros.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: pike_macros.h,v 1.14 2000/04/08 01:09:33 hubbe Exp $ + * $Id: pike_macros.h,v 1.15 2000/04/15 05:05:28 hubbe Exp $ */ #ifndef MACROS_H #define MACROS_H @@ -72,5 +72,27 @@ } \ free_program(p); \ }while(0) - + +#define DOUBLELINK(first_object, o) do { \ + o->next=first_object; \ + o->prev=0; \ + if(first_object) first_object->prev=o; \ + first_object=o; \ +}while(0) + +#define DOUBLEUNLINK(first_object,o) do{ \ + if(o->prev) { \ + o->prev->next=o->next; \ + }else { \ + DO_IF_DEBUG( \ + if(first_object != o) \ + fatal("Linked in wrong list!\n"); \ + ) \ + first_object=o->next; \ + } \ + \ + if(o->next) o->next->prev=o->prev; \ +}while(0) + + #endif diff --git a/src/pike_memory.c b/src/pike_memory.c index 0e4680582a2d446549a80e2059fc9a424685b48d..14b0b1c4b6ad1f9e3a2fd1d24124473b9f0c2212 100644 --- a/src/pike_memory.c +++ b/src/pike_memory.c @@ -10,7 +10,7 @@ #include "pike_macros.h" #include "gc.h" -RCSID("$Id: pike_memory.c,v 1.64 2000/04/12 18:40:12 hubbe Exp $"); +RCSID("$Id: pike_memory.c,v 1.65 2000/04/15 05:05:28 hubbe Exp $"); /* strdup() is used by several modules, so let's provide it */ #ifndef HAVE_STRDUP @@ -825,7 +825,7 @@ void check_pad(struct memhdr *mh, int freeok) if(!freeok) { fprintf(stderr,"Access to free block: %p (size %ld)!\n",mem, ~mh->size); - dump_memhdr_locations(mh, 0); + dump_memhdr_locations(mh, 0, 0); abort(); }else{ size = ~size; @@ -1363,7 +1363,7 @@ void dmalloc_check_block_free(void *p) if(mh && mh->size>=0 && !(mh->flags & MEM_IGNORE_LEAK)) { fprintf(stderr,"Freeing storage for small block still in use %p.\n",p); - debug_malloc_dump_references(p); + debug_malloc_dump_references(p,0,2,0); } mt_unlock(&debug_malloc_mutex); @@ -1417,8 +1417,8 @@ void *__wrap_strdup(const char *s) void low_dump_memhdr_locations(struct memhdr *from, - struct memhdr *notfrom, - int indent) + struct memhdr *notfrom, + int indent) { struct memloc *l; if(!from) return; @@ -1447,15 +1447,16 @@ void low_dump_memhdr_locations(struct memhdr *from, } void dump_memhdr_locations(struct memhdr *from, - struct memhdr *notfrom) + struct memhdr *notfrom, + int indent) { - low_dump_memhdr_locations(from,notfrom, 2); + low_dump_memhdr_locations(from,notfrom, indent); } -static void low_dmalloc_describe_location(struct memhdr *mh, int offset); +static void low_dmalloc_describe_location(struct memhdr *mh, int offset, int indent); -static void find_references_to(void *block) +static void find_references_to(void *block, int indent, int depth, int flags) { unsigned long h; struct memhdr *m; @@ -1477,9 +1478,9 @@ static void find_references_to(void *block) if(p[e] == block) { /* fprintf(stderr," <from %p word %d>\n",p,e); */ - describe_location(p,T_UNKNOWN,p+e); + describe_location(p,T_UNKNOWN,p+e, indent,depth,flags); - low_dmalloc_describe_location(m, e * sizeof(void *)); + low_dmalloc_describe_location(m, e * sizeof(void *), indent); m->flags |= MEM_WARN_ON_FREE; } @@ -1495,7 +1496,7 @@ static void find_references_to(void *block) void dmalloc_find_references_to(void *block) { mt_lock(&debug_malloc_mutex); - find_references_to(block); + find_references_to(block, 2, 1, 0); mt_unlock(&debug_malloc_mutex); } @@ -1505,8 +1506,6 @@ void *dmalloc_find_memblock_base(void *ptr) struct memhdr *m; char *lookfor=(char *)ptr; - mt_lock(&debug_malloc_mutex); - for(h=0;h<(unsigned long)memhdr_hash_table_size;h++) { for(m=memhdr_hash_table[h];m;m=m->next) @@ -1517,7 +1516,7 @@ void *dmalloc_find_memblock_base(void *ptr) if( ! ((sizeof(void *)-1) & (long) p )) { - if( m->data <= lookfor && lookfor < m->data + m->size) + if( p <= lookfor && lookfor < p + m->size) { mt_unlock(&debug_malloc_mutex); return m->data; @@ -1526,11 +1525,11 @@ void *dmalloc_find_memblock_base(void *ptr) } } - mt_unlock(&debug_malloc_mutex); return 0; } -void debug_malloc_dump_references(void *x) +/* FIXME: lock the mutex */ +void debug_malloc_dump_references(void *x, int indent, int depth, int flags) { struct memhdr *mh=my_find_memhdr(x,0); if(!mh) return; @@ -1538,19 +1537,20 @@ void debug_malloc_dump_references(void *x) { if(mh->flags & MEM_IGNORE_LEAK) { - fprintf(stderr,"<<<This leak has been ignored>>>\n"); + fprintf(stderr,"%*s<<<This leak has been ignored>>>\n",indent,""); } else if(mh->flags & MEM_REFERENCED) { - fprintf(stderr,"<<<Possibly referenced>>>\n"); - find_references_to(x); + fprintf(stderr,"%*s<<<Possibly referenced>>>\n",indent,""); + if(!(flags & 2)) + find_references_to(x,indent+2,depth-1,flags); } else { - fprintf(stderr,"<<<=- No known references to this block -=>>>\n"); + fprintf(stderr,"%*s<<<=- No known references to this block -=>>>\n",indent,""); } } - dump_memhdr_locations(mh,0); + dump_memhdr_locations(mh,0, indent+2); } void list_open_fds(void) @@ -1573,7 +1573,7 @@ void list_open_fds(void) { fprintf(stderr,"Filedescriptor %ld\n",PTR2FD(p)); - dump_memhdr_locations(m, 0); + dump_memhdr_locations(m, 0, 0); } } } @@ -1673,7 +1673,7 @@ void cleanup_memhdrs(void) } }else{ #ifdef PIKE_DEBUG - describe_something(p, attempt_to_identify(p),0); + describe_something(p, attempt_to_identify(p),0,2,8); #endif } mt_lock(&debug_malloc_mutex); @@ -1691,8 +1691,8 @@ void cleanup_memhdrs(void) break; } - find_references_to(p); - dump_memhdr_locations(m, 0); + find_references_to(p,0,2,0); + dump_memhdr_locations(m, 0,0); } } @@ -1996,7 +1996,7 @@ static void very_low_dmalloc_describe_location(struct memory_map *m, int indent) { struct memory_map_entry *e; - fprintf(stderr,"%*s ** In memory map %s:\n",indent,"",m->name+2); + fprintf(stderr,"%*s ** In memory description %s:\n",indent,"",m->name+2); for(e=m->entries;e;e=e->next) { if(e->offset <= offset && e->offset + e->size * e->count > offset) @@ -2004,10 +2004,12 @@ static void very_low_dmalloc_describe_location(struct memory_map *m, int num=(offset - e->offset)/e->size; int off=offset-e->size*num-e->offset; fprintf(stderr,"%*s Found in member: %s[%d] + %d (offset=%d size=%d)\n", - off, indent,"", + e->name, num, - e->name,e->offset,e->size); + off, + e->offset, + e->size); if(e->recur) { @@ -2019,7 +2021,7 @@ static void very_low_dmalloc_describe_location(struct memory_map *m, } } -static void low_dmalloc_describe_location(struct memhdr *mh, int offset) +static void low_dmalloc_describe_location(struct memhdr *mh, int offset, int indent) { struct memloc *l; for(l=mh->locations;l;l=l->next) @@ -2027,18 +2029,18 @@ static void low_dmalloc_describe_location(struct memhdr *mh, int offset) if(l->location[0]=='M') { struct memory_map *m = (struct memory_map *)(l->location - 1); - very_low_dmalloc_describe_location(m, offset,4); + very_low_dmalloc_describe_location(m, offset, indent); } } } -void dmalloc_describe_location(void *p, int offset) +void dmalloc_describe_location(void *p, int offset, int indent) { if(p) { struct memhdr *mh; mt_lock(&debug_malloc_mutex); - if((mh=my_find_memhdr(p,0))) low_dmalloc_describe_location(mh, offset); + if((mh=my_find_memhdr(p,0))) low_dmalloc_describe_location(mh, offset, indent); mt_unlock(&debug_malloc_mutex); } } @@ -2079,7 +2081,7 @@ void dmalloc_add_mmap_entry(struct memory_map *m, e->count=count?count:1; e->next=m->entries; e->recur=recur; - e->recur=recur_offset; + e->recur_offset=recur_offset; m->entries=e; mt_unlock(&debug_malloc_mutex); } diff --git a/src/program.c b/src/program.c index 4504e2f16270f04adb35cd9663bdbf82dd5e993a..e6cc2a8f44f96e8144e9e29321a5c249dddb3cd2 100644 --- a/src/program.c +++ b/src/program.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: program.c,v 1.225 2000/04/13 12:16:14 grubba Exp $"); +RCSID("$Id: program.c,v 1.226 2000/04/15 05:05:28 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -546,6 +546,30 @@ int program_function_index_compare(const void *a,const void *b) ID_FROM_INT(new_program, *(unsigned short *)b)->name); } +#ifdef PIKE_DEBUG +char *find_program_name(struct program *p, INT32 *line) +{ + INT32 pos; + +#ifdef DEBUG_MALLOC + char *tmp=dmalloc_find_name(p); + *line=0; + if(tmp) return tmp; +#endif + + /* Didn't find a given name, revert to ad-hoc method */ + + for(pos=0;pos<100;pos++) + { + tmp=get_line(p->program+pos, p, line); + if(tmp && *line) return tmp; + if(pos+1>=(long)p->num_program) break; + } + *line=0; + return 0; +} +#endif + void fixate_program(void) { INT32 i,e,t; @@ -600,8 +624,23 @@ void fixate_program(void) { #define DBSTR(X) ((X)?(X)->str:"") int e,v; - struct memory_map *m=dmalloc_alloc_mmap( DBSTR(lex.current_file), - lex.current_line); + INT32 line; + char *tmp; + struct memory_map *m=0;; + if(lex.current_file && + lex.current_file->str && + lex.current_file->len && + !strcmp(lex.current_file->str,"-")) + { + m=dmalloc_alloc_mmap( DBSTR(lex.current_file), lex.current_line); + } + else if( (tmp=find_program_name(new_program, &line)) ) + { + m=dmalloc_alloc_mmap( tmp, line); + }else{ + m=dmalloc_alloc_mmap( "program id", new_program->id); + } + for(e=0;e<new_program->num_inherits;e++) { struct inherit *i=new_program->inherits+e; @@ -624,21 +663,11 @@ void fixate_program(void) if(i->name) { tmp=i->name->str; - }else if(!(tmp=dmalloc_find_name(i->prog))){ - /* Didn't find a given name, revert to ad-hoc method */ - INT32 line,pos; - - for(pos=0;pos<100;pos++) - { - tmp=get_line(i->prog->program+pos, i->prog, &line); - if(tmp && line) break; - if(pos+1>=(long)i->prog->num_program) break; - } - if(!(tmp && line)) - { - sprintf(buffer,"inherit[%d]",e); - tmp=buffer; - } + } + else if(!(tmp=find_program_name(i->prog, &line))) + { + sprintf(buffer,"inherit[%d]",e); + tmp=buffer; } dmalloc_add_mmap_entry(m, tmp, diff --git a/src/stralloc.c b/src/stralloc.c index cf4e55788907253efe263cf76b5dd2b1053c8386..1110f29202e8db501e908e8a3cc7f4a41099b625 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -25,7 +25,7 @@ #define HUGE HUGE_VAL #endif /*!HUGE*/ -RCSID("$Id: stralloc.c,v 1.81 2000/04/01 07:27:02 hubbe Exp $"); +RCSID("$Id: stralloc.c,v 1.82 2000/04/15 05:05:28 hubbe Exp $"); #define BEGIN_HASH_SIZE 997 #define MAX_AVG_LINK_LENGTH 3 @@ -258,10 +258,10 @@ static void locate_problem(int (*isproblem)(struct pike_string *)) } DM(fprintf(stderr,"Plausible problem location(s):\n")); - DM(dump_memhdr_locations(yes,0)); + DM(dump_memhdr_locations(yes,0,0)); DM(fprintf(stderr,"More Plausible problem location(s):\n")); - DM(dump_memhdr_locations(yes,no)); + DM(dump_memhdr_locations(yes,no,0)); } static int has_zero_refs(struct pike_string *s) diff --git a/src/svalue.h b/src/svalue.h index 6af8292baa64fea547a7e52f83b52a7f270e85cb..d951060da282f3e68f62368d1c9a7cade09452a8 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: svalue.h,v 1.50 2000/04/12 10:39:09 grubba Exp $ + * $Id: svalue.h,v 1.51 2000/04/15 05:05:28 hubbe Exp $ */ #ifndef SVALUE_H #define SVALUE_H @@ -250,9 +250,20 @@ do{ \ }while(0) #ifdef PIKE_DEBUG +extern void describe(void *); /* defined in gc.c */ #define check_type(T) if(T > MAX_TYPE && T!=T_LVALUE && T!=T_SHORT_LVALUE && T!=T_VOID && T!=T_DELETED && T!=T_ARRAY_LVALUE) fatal("Type error: %d\n",T) -#define check_refs(S) if((S)->type < MAX_REF_TYPE && (!(S)->u.refs || (S)->u.refs[0] < 0)) fatal("Svalue to object without references.\n") -#define check_refs2(S,T) if((T) < MAX_REF_TYPE && (S)->refs && (S)->refs[0] <= 0) fatal("Svalue to object without references.\n") + +#define check_refs(S) do {\ + if((S)->type < MAX_REF_TYPE && (!(S)->u.refs || (S)->u.refs[0] < 0)) { \ + describe((S)->u.refs); \ + fatal("Svalue to object without references.\n"); \ +} }while(0) + +#define check_refs2(S,T) do { \ +if((T) < MAX_REF_TYPE && (S)->refs && (S)->refs[0] <= 0) {\ + describe((S)->refs); \ + fatal("(short) Svalue to object without references.\n"); \ +} }while(0) #ifdef DEBUG_MALLOC #define add_ref(X) ((INT32 *)debug_malloc_pass( &((X)->refs)))[0]++ diff --git a/src/threads.c b/src/threads.c index 6af340da93ed76522bd28228d84ad506577b8e57..23d3b57ad61dfc067e0d864302e6fea892ca835c 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.118 2000/04/12 16:54:42 hubbe Exp $"); +RCSID("$Id: threads.c,v 1.119 2000/04/15 05:05:28 hubbe Exp $"); int num_threads = 1; int threads_disabled = 0; @@ -579,8 +579,8 @@ TH_RETURN_TYPE new_thread_func(void * data) THREAD_T self = th_self(); if( thread_id && !th_equal( OBJ2THREAD(thread_id)->id, self) ) - fatal("Current thread is wrong. %x %x\n", - OBJ2THREAD(thread_id)->id, self); + fatal("Current thread is wrong. %lx %lx\n", + (long)OBJ2THREAD(thread_id)->id, (long)self); if(thread_for_id(th_self()) != thread_id) fatal("thread_for_id() (or thread_id) failed in new_thread_func! " diff --git a/src/threads.h b/src/threads.h index b7360482687fb2ee0ebd845ddacb1c711775926f..6e4580e8c88fab11f1d2e2ef842ef4516ea19caa 100644 --- a/src/threads.h +++ b/src/threads.h @@ -1,5 +1,5 @@ /* - * $Id: threads.h,v 1.80 2000/04/14 17:44:45 mast Exp $ + * $Id: threads.h,v 1.81 2000/04/15 05:05:28 hubbe Exp $ */ #ifndef THREADS_H #define THREADS_H @@ -469,7 +469,7 @@ struct thread_state { DO_IF_DEBUG({ \ if(thread_for_id(th_self()) != thread_id) \ fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id); \ - if (Pike_in_gc == 1 || Pike_in_gc == 2) \ + if (Pike_in_gc >0 && Pike_in_gc <4) \ fatal("Threads allowed during garbage collection.\n"); \ }) \ if(num_threads > 1 && !threads_disabled) { \ @@ -504,7 +504,7 @@ struct thread_state { DO_IF_DEBUG({ \ if(thread_for_id(th_self()) != thread_id) \ fatal("thread_for_id() (or thread_id) failed! %p != %p\n",thread_for_id(th_self()),thread_id); \ - if (Pike_in_gc == 1 || Pike_in_gc == 2) \ + if (Pike_in_gc >0 && Pike_in_gc <4) \ fatal("Threads allowed during garbage collection.\n"); \ }) \ if(num_threads > 1 && !threads_disabled) { \