diff --git a/src/block_alloc.h b/src/block_alloc.h index 202c3ce811eae76679ff44983da5a14df1dba8ee..fefb0fe44658a5a87ca02252215bad27f17261df 100644 --- a/src/block_alloc.h +++ b/src/block_alloc.h @@ -1,4 +1,4 @@ -/* $Id: block_alloc.h,v 1.17 2000/03/22 00:55:07 hubbe Exp $ */ +/* $Id: block_alloc.h,v 1.18 2000/03/24 01:24:49 hubbe Exp $ */ #undef PRE_INIT_BLOCK #undef INIT_BLOCK #undef EXIT_BLOCK @@ -51,7 +51,7 @@ struct DATA *PIKE_CONCAT(alloc_,DATA)(void) \ \ tmp=PIKE_CONCAT3(free_,DATA,s); \ PIKE_CONCAT3(free_,DATA,s)=tmp->BLOCK_ALLOC_NEXT; \ - DO_IF_DMALLOC( dmalloc_register(tmp,0, DMALLOC_LOCATION()); ) \ + DO_IF_DMALLOC( dmalloc_register(tmp,sizeof(struct DATA), DMALLOC_LOCATION()); )\ INIT_BLOCK(tmp); \ return tmp; \ } \ @@ -68,6 +68,15 @@ void PIKE_CONCAT(really_free_,DATA)(struct DATA *d) \ void PIKE_CONCAT3(free_all_,DATA,_blocks)(void) \ { \ struct PIKE_CONCAT(DATA,_block) *tmp; \ + DO_IF_DMALLOC( \ + for(tmp=PIKE_CONCAT(DATA,_blocks);tmp;tmp=tmp->next) \ + { \ + int tmp2; \ + extern void dmalloc_check_block_free(void *p); \ + for(tmp2=0;tmp2<BSIZE;tmp2++) \ + dmalloc_check_block_free(tmp->x+tmp2); \ + } \ + ) \ while((tmp=PIKE_CONCAT(DATA,_blocks))) \ { \ PIKE_CONCAT(DATA,_blocks)=tmp->next; \ diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 55365f64680f783938ff5c391fe6dc651715cfa6..a6938b205b6470669e2122f0c22177c34f5c0730 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.245 2000/03/20 21:00:03 hubbe Exp $"); +RCSID("$Id: builtin_functions.c,v 1.246 2000/03/24 01:24:49 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -595,6 +595,7 @@ void f_backtrace(INT32 args) { char *program_name; + debug_malloc_touch(f); frames--; if(f->current_object && f->context.prog) @@ -2823,7 +2824,7 @@ void f_localtime(INT32 args) #endif #ifdef HAVE_MKTIME -static void f_mktime (INT32 args) +void f_mktime (INT32 args) { INT_TYPE sec, min, hour, mday, mon, year, isdst; struct tm date; diff --git a/src/errors.h b/src/errors.h index 6da9d52d2714a91490c9896d615b09beb5b2f359..9dbb3238aae7053e9127ebc7cc22775d4f719e48 100644 --- a/src/errors.h +++ b/src/errors.h @@ -68,7 +68,7 @@ DECLARE_ERROR(generic, EMPTY , ERR_FUNC("backtrace",f_error_backtrace,tFunc(tVoid,tArr(tMixed)),0) ) -#define GENERIC_ERROR_THIS ((struct generic_error_struct *)Pike_fp->current_storage) +#define GENERIC_ERROR_THIS ((struct generic_error_struct *)CURRENT_STORAGE) DECLARE_ERROR(index, ERR_INHERIT(generic), diff --git a/src/interpret.c b/src/interpret.c index ff24aff887d3b113c1196153370d67526c68ba27..a53e9e6acf31e3df075f6be72a078c5ca3eb0020 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: interpret.c,v 1.136 2000/02/15 02:39:01 grubba Exp $"); +RCSID("$Id: interpret.c,v 1.137 2000/03/24 01:24:49 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -617,6 +617,13 @@ static void do_trace_call(INT32 args) free_svalues(X->locals,X->num_locals,BIT_MIXED); \ free((char *)(X->locals)); \ } \ + DO_IF_DMALLOC( \ + X->context.prog=0; \ + X->context.parent=0; \ + X->scope=0; \ + X->malloced_locals=0; \ + X->locals=0; \ + ) \ }while(0) BLOCK_ALLOC(pike_frame,128) @@ -996,6 +1003,7 @@ void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2) int num_args; int num_locals; unsigned char *pc; + debug_malloc_touch(fp); pc=new_frame->context.prog->program + function->func.offset; num_locals=EXTRACT_UCHAR(pc++); diff --git a/src/interpret.h b/src/interpret.h index 0e80c689df6bcbf45ff6c40179b08fab14f420b3..67c11a5b8442f95b2b57ab4b7a213c718362f92f 100644 --- a/src/interpret.h +++ b/src/interpret.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: interpret.h,v 1.37 2000/02/29 03:17:24 hubbe Exp $ + * $Id: interpret.h,v 1.38 2000/03/24 01:24:49 hubbe Exp $ */ #ifndef INTERPRET_H #define INTERPRET_H @@ -242,6 +242,8 @@ extern long long time_base; #endif /* !NO_PIKE_SHORTHAND */ +#define CURRENT_STORAGE (dmalloc_touch(struct pike_frame *,Pike_fp)->current_storage) + #endif diff --git a/src/interpreter.h b/src/interpreter.h index 69090f1a2285b815bbd45c980afb031062c5c688..436ff8462a5010bc4fa7d735bb56a24894b73df1 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -86,7 +86,7 @@ static int eval_instruction(unsigned char *pc) case 2: check_object_context(Pike_fp->current_object, Pike_fp->context.prog, - Pike_fp->current_storage); + CURRENT_STORAGE); case 1: case 0: break; diff --git a/src/object.c b/src/object.c index 0ba765a49a5d1a244f9d7664b85303c6040b719c..abba89fad0a656ac1fc4474c28ce42911ec177d5 100644 --- a/src/object.c +++ b/src/object.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: object.c,v 1.94 2000/03/20 21:00:04 hubbe Exp $"); +RCSID("$Id: object.c,v 1.95 2000/03/24 01:24:49 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -1298,7 +1298,7 @@ struct magic_index_struct struct object *o; }; -#define MAGIC_THIS ((struct magic_index_struct *)(fp->current_storage)) +#define MAGIC_THIS ((struct magic_index_struct *)(CURRENT_STORAGE)) #define MAGIC_O2S(o) ((struct magic_index_struct *)&(o->storage)) struct program *magic_index_program=0; diff --git a/src/operators.c b/src/operators.c index bcfb155002bf95d21692b2bf5a335ed1254bdb92..e5224b559ee988cc53594d8a48bc2c3a9eb35795 100644 --- a/src/operators.c +++ b/src/operators.c @@ -6,7 +6,7 @@ /**/ #include "global.h" #include <math.h> -RCSID("$Id: operators.c,v 1.86 2000/03/01 08:40:52 hubbe Exp $"); +RCSID("$Id: operators.c,v 1.87 2000/03/24 01:24:50 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "multiset.h" @@ -2381,7 +2381,7 @@ static int generate_call_function(node *n) struct program *string_assignment_program; #undef THIS -#define THIS ((struct string_assignment_storage *)(fp->current_storage)) +#define THIS ((struct string_assignment_storage *)(CURRENT_STORAGE)) static void f_string_assignment_index(INT32 args) { INT32 i; diff --git a/src/pike_memory.c b/src/pike_memory.c index fbc151afbb3ff29988938dbfde1884044bcaf990..4c935240e54a9d31a33bdf1d33dc1908272b2979 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.58 2000/03/22 00:56:54 hubbe Exp $"); +RCSID("$Id: pike_memory.c,v 1.59 2000/03/24 01:24:51 hubbe Exp $"); /* strdup() is used by several modules, so let's provide it */ #ifndef HAVE_STRDUP @@ -733,6 +733,9 @@ struct memloc }; #define MEM_PADDED 1 +#define MEM_WARN_ON_FREE 2 +#define MEM_REFERENCED 4 +#define MEM_IGNORE_LEAK 8 BLOCK_ALLOC(memloc, 16382) @@ -752,8 +755,6 @@ static struct memloc *mlhash[LHSIZE]; static char rndbuf[RNDSIZE + DEBUG_MALLOC_PAD*2]; static struct memhdr no_leak_memlocs; -static LOCATION loc_accepted_leak="*acceptable leak*"; -static LOCATION loc_referenced="*referenced*"; static int memheader_references_located=0; @@ -1201,7 +1202,8 @@ void dmalloc_accept_leak(void *p) { struct memhdr *mh; mt_lock(&debug_malloc_mutex); - if((mh=my_find_memhdr(p,0))) add_location(mh, loc_accepted_leak); + if((mh=my_find_memhdr(p,0))) + mh->flags |= MEM_IGNORE_LEAK; mt_unlock(&debug_malloc_mutex); } } @@ -1286,10 +1288,12 @@ void debug_free(void *p, LOCATION location, int mustfind) struct memhdr *mh; if(!p) return; mt_lock(&debug_malloc_mutex); - if(verbose_debug_malloc) - fprintf(stderr, "free(%p) (%s)\n", p, LOCATION_NAME(location)); + mh=my_find_memhdr(p,0); + if(verbose_debug_malloc || (mh->flags & MEM_WARN_ON_FREE)) + fprintf(stderr, "free(%p) (%s)\n", p, LOCATION_NAME(location)); + if(!mh && mustfind && p) { fprintf(stderr,"Lost track of a mustfind memory block: %p!\n",p); @@ -1338,6 +1342,21 @@ void debug_free(void *p, LOCATION location, int mustfind) mt_unlock(&debug_malloc_mutex); } +void dmalloc_check_block_free(void *p) +{ + struct memhdr *mh; + mt_lock(&debug_malloc_mutex); + mh=my_find_memhdr(p,0); + + 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); + } + + mt_unlock(&debug_malloc_mutex); +} + void dmalloc_free(void *p) { debug_free(p, DMALLOC_LOCATION(), 0); @@ -1376,38 +1395,66 @@ void dump_memhdr_locations(struct memhdr *from, LOCATION_IS_DYNAMIC(l->location) ? "-->" : "***", LOCATION_NAME(l->location), l->times, - find_location(&no_leak_memlocs, l->location) ? "" : "*"); + find_location(&no_leak_memlocs, l->location) ? "" : + ( from->flags & MEM_REFERENCED ? "*" : "!*!") + ); } } +static void find_references_to(void *block) +{ + unsigned long h; + struct memhdr *m; + + for(h=0;h<(unsigned long)memhdr_hash_table_size;h++) + { + for(m=memhdr_hash_table[h];m;m=m->next) + { + unsigned int e; + struct memhdr *tmp; + void **p=m->data; + + if( ! ((sizeof(void *)-1) & (long) p )) + { + if(m->size > 0) + { + for(e=0;e<m->size/sizeof(void *);e++) + { + if(p[e] == block) + { + fprintf(stderr," <from %p word %d>\n",p,e); + m->flags |= MEM_WARN_ON_FREE; + } + } + } + } + } + } + + memheader_references_located=1; +} + void debug_malloc_dump_references(void *x) { struct memhdr *mh=my_find_memhdr(x,0); if(!mh) return; if(memheader_references_located) { - int referenced=0; - struct memloc *l; - - for(l=mh->locations;l;l=l->next) - { - if(l->location == loc_accepted_leak) referenced|=2; - if(l->location == loc_referenced) referenced|=1; - } - if(referenced & 2) + if(mh->flags & MEM_IGNORE_LEAK) { fprintf(stderr,"<<<This leak has been ignored>>>\n"); } - else if(referenced & 1) + else if(mh->flags & MEM_REFERENCED) { fprintf(stderr,"<<<Possibly referenced>>>\n"); + find_references_to(x); } else { fprintf(stderr,"<<<=- No known references to this block -=>>>\n"); } } - dump_memhdr_locations(my_find_memhdr(x,0),0); + dump_memhdr_locations(mh,0); } void list_open_fds(void) @@ -1443,9 +1490,10 @@ static void low_search_all_memheaders_for_references(void) unsigned long h; struct memhdr *m; + for(h=0;h<(unsigned long)memhdr_hash_table_size;h++) for(m=memhdr_hash_table[h];m;m=m->next) - remove_location(m, loc_referenced); + m->flags &=~ MEM_REFERENCED; for(h=0;h<(unsigned long)memhdr_hash_table_size;h++) { @@ -1461,7 +1509,7 @@ static void low_search_all_memheaders_for_references(void) { for(e=0;e<m->size/sizeof(void *);e++) if((tmp=find_memhdr(p[e]))) - add_location(tmp, loc_referenced); + tmp->flags |= MEM_REFERENCED; } } } @@ -1505,16 +1553,9 @@ void cleanup_memhdrs(void) { int referenced=0; struct memhdr *tmp; - struct memloc *l; void *p=m->data; - for(l=m->locations;l;l=l->next) - { - if(l->location == loc_accepted_leak) referenced|=2; - if(l->location == loc_referenced) referenced|=1; - } - - if(referenced & 2) continue; + if(m->flags & MEM_IGNORE_LEAK) continue; mt_unlock(&debug_malloc_mutex); if(first) @@ -1523,7 +1564,7 @@ void cleanup_memhdrs(void) first=0; } - if(referenced & 1) + if(m->flags & MEM_REFERENCED) fprintf(stderr, "possibly referenced memory: (%p) %ld bytes\n",p, m->size); else fprintf(stderr, "==LEAK==: (%p) %ld bytes\n",p, m->size); @@ -1598,10 +1639,10 @@ static void unlock_da_lock(void) int main(int argc, char *argv[]) { - int e; + long e; extern int dbm_main(int, char **); - for(e=0;e<NELEM(rndbuf);e++) rndbuf[e]= (rand() % 511) | 1; + for(e=0;e<(long)NELEM(rndbuf);e++) rndbuf[e]= (rand() % 511) | 1; #if DEBUG_MALLOC_PAD & 3 fprintf(stderr,"DEBUG_MALLOC_PAD not dividable by four!\n"); diff --git a/src/program.c b/src/program.c index 57716f2a672ec47ce9d508695e8dc1daec3353c2..62eb15d8ddfd7e097deff26cd5ef86ea35f410ca 100644 --- a/src/program.c +++ b/src/program.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: program.c,v 1.213 2000/03/17 05:13:17 hubbe Exp $"); +RCSID("$Id: program.c,v 1.214 2000/03/24 01:24:51 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -3238,7 +3238,7 @@ void check_all_programs(void) #endif #undef THIS -#define THIS ((struct pike_trampoline *)(fp->current_storage)) +#define THIS ((struct pike_trampoline *)(CURRENT_STORAGE)) struct program *pike_trampoline_program=0; static void apply_trampoline(INT32 args) diff --git a/src/security.c b/src/security.c index 00a64eaf875b75fd226c5a5cd2369f0bd9c28b5a..9cb98e0895726697de4707449636c8857422ff59 100644 --- a/src/security.c +++ b/src/security.c @@ -55,7 +55,7 @@ static struct program *creds_program; struct object *current_creds=0; #undef THIS -#define THIS ((struct pike_creds *)(fp->current_storage)) +#define THIS ((struct pike_creds *)(CURRENT_STORAGE)) static int valid_creds_object(struct object *o) { diff --git a/src/signal_handler.c b/src/signal_handler.c index fb2b5d78cd128b15ae4c92fbce6a2cce9681af3c..9ed267d49ede498e6030d8d3587b8ec06bcb9703 100644 --- a/src/signal_handler.c +++ b/src/signal_handler.c @@ -25,7 +25,7 @@ #include "main.h" #include <signal.h> -RCSID("$Id: signal_handler.c,v 1.167 2000/03/22 00:56:14 hubbe Exp $"); +RCSID("$Id: signal_handler.c,v 1.168 2000/03/24 01:24:52 hubbe Exp $"); #ifdef HAVE_PASSWD_H # include <passwd.h> @@ -898,7 +898,7 @@ static RETSIGTYPE receive_sigchild(int signum) #define PROCESS_EXITED 1 #undef THIS -#define THIS ((struct pid_status *)fp->current_storage) +#define THIS ((struct pid_status *)CURRENT_STORAGE) #ifdef USE_PID_MAPPING static struct mapping *pid_mapping=0; diff --git a/src/threads.c b/src/threads.c index 3e3d96e4fca61e67d427d8be39881b7ea7009207..6380eed1a5371f59f66446492008f9ff23fd6347 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.112 2000/03/17 05:12:30 hubbe Exp $"); +RCSID("$Id: threads.c,v 1.113 2000/03/24 01:24:52 hubbe Exp $"); int num_threads = 1; int threads_disabled = 0; @@ -194,7 +194,7 @@ int co_destroy(COND_T *c) #endif -#define THIS_THREAD ((struct thread_state *)fp->current_storage) +#define THIS_THREAD ((struct thread_state *)CURRENT_STORAGE) struct object *thread_id = NULL; static struct callback *threads_evaluator_callback=0; @@ -632,10 +632,14 @@ TH_RETURN_TYPE new_thread_func(void * data) THREADS_FPRINTF(0, (stderr,"THREADS_ALLOW() Thread %08x done\n", (unsigned int)thread_id)); + cleanup_interpret(); + DO_IF_DMALLOC( + SWAP_OUT_THREAD(OBJ2THREAD(thread_id)); /* de-Init struct */ + OBJ2THREAD(thread_id)->swapped=0; + ) thread_table_delete(thread_id); free_object(thread_id); thread_id=0; - cleanup_interpret(); num_threads--; if(!num_threads && threads_evaluator_callback) { @@ -708,7 +712,7 @@ void f_this_thread(INT32 args) ref_push_object(thread_id); } -#define THIS_MUTEX ((struct mutex_storage *)(fp->current_storage)) +#define THIS_MUTEX ((struct mutex_storage *)(CURRENT_STORAGE)) /* Note: @@ -880,7 +884,7 @@ void exit_mutex_obj(struct object *o) co_destroy(& THIS_MUTEX->condition); } -#define THIS_KEY ((struct key_storage *)(fp->current_storage)) +#define THIS_KEY ((struct key_storage *)(CURRENT_STORAGE)) void init_mutex_key_obj(struct object *o) { THREADS_FPRINTF(1, (stderr, "KEY k:%08x, o:%08x\n", @@ -916,7 +920,7 @@ void exit_mutex_key_obj(struct object *o) } } -#define THIS_COND ((COND_T *)(fp->current_storage)) +#define THIS_COND ((COND_T *)(CURRENT_STORAGE)) void f_cond_wait(INT32 args) { COND_T *c; @@ -1082,7 +1086,7 @@ void f_thread_local_get(INT32 args) { struct svalue key; struct mapping *m; - key.u.integer = ((struct thread_local *)fp->current_storage)->id; + key.u.integer = ((struct thread_local *)CURRENT_STORAGE)->id; key.type = T_INT; key.subtype = NUMBER_NUMBER; pop_n_elems(args); @@ -1099,7 +1103,7 @@ void f_thread_local_set(INT32 args) { struct svalue key; struct mapping *m; - key.u.integer = ((struct thread_local *)fp->current_storage)->id; + key.u.integer = ((struct thread_local *)CURRENT_STORAGE)->id; key.type = T_INT; key.subtype = NUMBER_NUMBER; if(args>1) diff --git a/src/threads.h b/src/threads.h index 73c4a6d2f3c16a43a59a3956b1a95f5a86e9a2ba..bebc3d4c33b9a80cbda5c99ed8f3b580883b46cb 100644 --- a/src/threads.h +++ b/src/threads.h @@ -1,5 +1,5 @@ /* - * $Id: threads.h,v 1.74 2000/02/20 10:23:21 hubbe Exp $ + * $Id: threads.h,v 1.75 2000/03/24 01:24:52 hubbe Exp $ */ #ifndef THREADS_H #define THREADS_H @@ -391,7 +391,7 @@ struct thread_state { (_tmp)->swapped=1; \ (_tmp)->Pike_evaluator_stack=Pike_evaluator_stack;\ (_tmp)->evaluator_stack_malloced=evaluator_stack_malloced;\ - (_tmp)->Pike_fp=Pike_fp;\ + debug_malloc_touch( (_tmp)->Pike_fp=Pike_fp );\ (_tmp)->Pike_mark_sp=Pike_mark_sp;\ (_tmp)->Pike_mark_stack=Pike_mark_stack;\ (_tmp)->mark_stack_malloced=mark_stack_malloced;\ @@ -409,7 +409,7 @@ struct thread_state { (_tmp)->swapped=0; \ Pike_evaluator_stack=(_tmp)->Pike_evaluator_stack;\ evaluator_stack_malloced=(_tmp)->evaluator_stack_malloced;\ - Pike_fp=(_tmp)->Pike_fp;\ + debug_malloc_touch( Pike_fp=(_tmp)->Pike_fp );\ Pike_mark_sp=(_tmp)->Pike_mark_sp;\ Pike_mark_stack=(_tmp)->Pike_mark_stack;\ mark_stack_malloced=(_tmp)->mark_stack_malloced;\