diff --git a/src/backend.c b/src/backend.c index 14b36774a147f971ffbfeaa030b02b70cc6698ce..3a8faae1e65e897de98de57ec89b48c798db1435 100644 --- a/src/backend.c +++ b/src/backend.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: backend.c,v 1.40 1998/11/22 11:02:33 hubbe Exp $"); +RCSID("$Id: backend.c,v 1.41 1999/05/02 08:11:28 hubbe Exp $"); #include "fdlib.h" #include "backend.h" #include <errno.h> @@ -184,7 +184,7 @@ static int may_need_wakeup=0; static struct callback_list backend_callbacks; -struct callback *add_backend_callback(callback_func call, +struct callback *debug_add_backend_callback(callback_func call, void *arg, callback_func free_func) { diff --git a/src/backend.h b/src/backend.h index b72d32fd3ad6823af71c1ec83600d23541b4cc89..09011754e6019ac4129dfd03a689f3ccce34f204 100644 --- a/src/backend.h +++ b/src/backend.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: backend.h,v 1.6 1998/03/28 15:39:44 grubba Exp $ + * $Id: backend.h,v 1.7 1999/05/02 08:11:29 hubbe Exp $ */ #ifndef BACKEND_H #define BACKEND_H @@ -21,7 +21,7 @@ extern struct callback_list do_debug_callbacks; /* Prototypes begin here */ struct selectors; -struct callback *add_backend_callback(callback_func call, +struct callback *debug_add_backend_callback(callback_func call, void *arg, callback_func free_func); void wake_up_backend(void); @@ -49,4 +49,7 @@ void backend(void); int write_to_stderr(char *a, INT32 len); /* Prototypes end here */ +#define add_backend_callback(X,Y,Z) \ + dmalloc_touch(struct callback *,debug_add_backend_callback((X),(Y),(Z))) + #endif diff --git a/src/block_alloc.h b/src/block_alloc.h index 2862f71e835e02fa9d5a8806f8f3ba02b0b02dc5..517a35dbda1c22796aa098c261c951e93448f6dc 100644 --- a/src/block_alloc.h +++ b/src/block_alloc.h @@ -1,4 +1,4 @@ -/* $Id: block_alloc.h,v 1.10 1999/04/08 22:27:06 hubbe Exp $ */ +/* $Id: block_alloc.h,v 1.11 1999/05/02 08:11:30 hubbe Exp $ */ #undef PRE_INIT_BLOCK #undef INIT_BLOCK #undef EXIT_BLOCK @@ -47,6 +47,7 @@ struct DATA *PIKE_CONCAT(alloc_,DATA)(void) \ \ tmp=PIKE_CONCAT3(free_,DATA,s); \ PIKE_CONCAT3(free_,DATA,s)=tmp->next; \ + DO_IF_DMALLOC( dmalloc_register(tmp,0, __FILE__, __LINE__); ) \ INIT_BLOCK(tmp); \ return tmp; \ } \ @@ -54,6 +55,7 @@ struct DATA *PIKE_CONCAT(alloc_,DATA)(void) \ void PIKE_CONCAT(really_free_,DATA)(struct DATA *d) \ { \ EXIT_BLOCK(d); \ + DO_IF_DMALLOC( dmalloc_unregister(d, 1); ) \ d->next=PIKE_CONCAT3(free_,DATA,s); \ PRE_INIT_BLOCK(d); \ PIKE_CONCAT3(free_,DATA,s)=d; \ @@ -70,6 +72,22 @@ void PIKE_CONCAT3(free_all_,DATA,_blocks)(void) \ PIKE_CONCAT(DATA,_blocks)=0; \ PIKE_CONCAT3(free_,DATA,s)=0; \ } \ + \ + \ +void PIKE_CONCAT3(count_memory_in_,DATA,s)(INT32 *num_, INT32 *size_) \ +{ \ + INT32 num=0, size=0; \ + struct PIKE_CONCAT(DATA,_block) *tmp; \ + struct DATA *tmp2; \ + for(tmp=PIKE_CONCAT(DATA,_blocks);tmp;tmp=tmp->next) \ + { \ + num+=BSIZE; \ + size+=sizeof(struct PIKE_CONCAT(DATA,_block)); \ + } \ + for(tmp2=PIKE_CONCAT3(free_,DATA,s);tmp2;tmp2=tmp2->next) num--; \ + *num_=num; \ + *size_=size; \ +} @@ -108,52 +126,59 @@ struct DATA *PIKE_CONCAT(find_,DATA)(void *ptr) \ } \ \ \ +static void PIKE_CONCAT(DATA,_rehash)() \ +{ \ + /* Time to re-hash */ \ + struct DATA **old_hash= PIKE_CONCAT(DATA,_hash_table); \ + struct DATA *p; \ + int hval; \ + int e=PIKE_CONCAT(DATA,_hash_table_size); \ + \ + PIKE_CONCAT(DATA,_hash_table_size)*=2; \ + PIKE_CONCAT(DATA,_hash_table_size)++; \ + if((PIKE_CONCAT(DATA,_hash_table)=(struct DATA **) \ + malloc(PIKE_CONCAT(DATA,_hash_table_size)* \ + sizeof(struct DATA *)))) \ + { \ + MEMSET(PIKE_CONCAT(DATA,_hash_table),0, \ + sizeof(struct DATA *)*PIKE_CONCAT(DATA,_hash_table_size)); \ + while(--e >=0) \ + { \ + while((p=old_hash[e])) \ + { \ + old_hash[e]=p->next; \ + hval=(long)(p-> data); \ + hval%=PIKE_CONCAT(DATA,_hash_table_size); \ + p->next=PIKE_CONCAT(DATA,_hash_table)[hval]; \ + PIKE_CONCAT(DATA,_hash_table)[hval]=p; \ + } \ + } \ + free((char *)old_hash); \ + }else{ \ + PIKE_CONCAT(DATA,_hash_table)=old_hash; \ + PIKE_CONCAT(DATA,_hash_table_size)=e; \ + } \ +} \ + \ \ -struct DATA *PIKE_CONCAT(make_,DATA)(void *ptr, int hval) \ +struct DATA *PIKE_CONCAT(make_,DATA)(void *ptr, int hval) \ { \ struct DATA *p; \ \ - DO_IF_DEBUG( if(!PIKE_CONCAT(DATA,_hash_table)) \ - fatal("Hash table error!\n"); ) \ + DO_IF_DEBUG( if(!PIKE_CONCAT(DATA,_hash_table)) \ + fatal("Hash table error!\n"); ) \ PIKE_CONCAT(num_,DATA)++; \ \ if(( PIKE_CONCAT(num_,DATA)>>2 ) >= \ PIKE_CONCAT(DATA,_hash_table_size)) \ { \ - /* Time to re-hash */ \ - struct DATA **old_hash= PIKE_CONCAT(DATA,_hash_table); \ - int e=PIKE_CONCAT(DATA,_hash_table_size); \ - \ - PIKE_CONCAT(DATA,_hash_table_size)*=2; \ - PIKE_CONCAT(DATA,_hash_table_size)++; \ - if((PIKE_CONCAT(DATA,_hash_table)=(struct DATA **) \ - malloc(PIKE_CONCAT(DATA,_hash_table_size)* \ - sizeof(struct DATA *)))) \ - { \ - MEMSET(PIKE_CONCAT(DATA,_hash_table),0, \ - sizeof(struct DATA *)*PIKE_CONCAT(DATA,_hash_table_size)); \ - while(e-- >=0) \ - { \ - while((p=old_hash[e])) \ - { \ - old_hash[e]=p->next; \ - hval=(long)(p-> data); \ - hval%=PIKE_CONCAT(DATA,_hash_table_size); \ - p->next=PIKE_CONCAT(DATA,_hash_table)[hval]; \ - PIKE_CONCAT(DATA,_hash_table)[hval]=p; \ - } \ - } \ - hval=(long)ptr; \ - hval%=PIKE_CONCAT(DATA,_hash_table_size); \ - free((char *)old_hash); \ - }else{ \ - PIKE_CONCAT(DATA,_hash_table)=old_hash; \ - PIKE_CONCAT(DATA,_hash_table_size)=e; \ - } \ + PIKE_CONCAT(DATA,_rehash)(); \ + hval=(long)ptr; \ + hval%=PIKE_CONCAT(DATA,_hash_table_size); \ } \ \ - p=PIKE_CONCAT(alloc_,DATA)(); \ - p->data=ptr; \ + p=PIKE_CONCAT(alloc_,DATA)(); \ + p->data=ptr; \ p->next=PIKE_CONCAT(DATA,_hash_table)[hval]; \ PIKE_CONCAT(DATA,_hash_table)[hval]=p; \ return p; \ @@ -186,12 +211,12 @@ int PIKE_CONCAT(remove_,DATA)(void *ptr) \ { \ struct DATA *p; \ int hval=(long)ptr; \ - if(!PIKE_CONCAT(DATA,_hash_table)) return 0; \ + if(!PIKE_CONCAT(DATA,_hash_table)) return 0; \ hval%=PIKE_CONCAT(DATA,_hash_table_size); \ if((p=PIKE_CONCAT(really_low_find_,DATA)(ptr, hval))) \ { \ PIKE_CONCAT(num_,DATA)--; \ - if(PIKE_CONCAT(DATA,_hash_table)[hval]!=p) fatal("GAOssdf\n"); \ + if(PIKE_CONCAT(DATA,_hash_table)[hval]!=p) fatal("GAOssdf\n"); \ PIKE_CONCAT(DATA,_hash_table)[hval]=p->next; \ PIKE_CONCAT(really_free_,DATA)(p); \ return 1; \ @@ -206,7 +231,12 @@ void PIKE_CONCAT3(init_,DATA,_hash)(void) \ PIKE_CONCAT(DATA,_hash_table_size)=hashprimes[my_log2(BSIZE)]; \ \ PIKE_CONCAT(DATA,_hash_table)=(struct DATA **) \ - xalloc(sizeof(struct DATA *)*PIKE_CONCAT(DATA,_hash_table_size)); \ + malloc(sizeof(struct DATA *)*PIKE_CONCAT(DATA,_hash_table_size)); \ + if(!PIKE_CONCAT(DATA,_hash_table)) \ + { \ + fprintf(stderr,"Fatal: out of memory.\n"); \ + exit(17); \ + } \ MEMSET(PIKE_CONCAT(DATA,_hash_table),0, \ sizeof(struct DATA *)*PIKE_CONCAT(DATA,_hash_table_size)); \ } \ @@ -216,5 +246,5 @@ void PIKE_CONCAT3(exit_,DATA,_hash)(void) \ PIKE_CONCAT3(free_all_,DATA,_blocks)(); \ free(PIKE_CONCAT(DATA,_hash_table)); \ PIKE_CONCAT(DATA,_hash_table)=0; \ -} \ +} diff --git a/src/block_alloc_h.h b/src/block_alloc_h.h index a3c47e0a63639f2dc860bb4906e0f12f281a16d5..39432dd8d87ab8f9da96ee1b8045f31b880e8064 100644 --- a/src/block_alloc_h.h +++ b/src/block_alloc_h.h @@ -5,6 +5,7 @@ struct DATA *PIKE_CONCAT(alloc_,DATA)(void); \ void PIKE_CONCAT(really_free_,DATA)(struct DATA *d); \ void PIKE_CONCAT3(free_all_,DATA,_blocks)(void); +void PIKE_CONCAT3(count_memory_in_,DATA,s)(INT32 *, INT32 *); \ #define PTR_HASH_ALLOC(DATA,BSIZE) \ diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 8f020bf12fe1bb3640703c3724d240e260550fdf..d3f691b795b44944ee1aba9f6a4340e5710ad490 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.167 1999/04/17 13:45:52 grubba Exp $"); +RCSID("$Id: builtin_functions.c,v 1.168 1999/05/02 08:11:32 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -3506,6 +3506,12 @@ void f__memory_usage(INT32 args) push_text("callable_bytes"); push_int(size); + count_memory_in_pike_frames(&num, &size); + push_text("num_frames"); + push_int(num); + push_text("frame_bytes"); + push_int(size); + call_callback(&memory_usage_callback, (void *)0); f_aggregate_mapping(sp-ss); diff --git a/src/callback.c b/src/callback.c index 53cb8a6ae8b6aa51c9f164a8b3ff83b62ea74366..a371ab50bb9fefd77b9fad177edeeb7c6ea9b748 100644 --- a/src/callback.c +++ b/src/callback.c @@ -9,7 +9,7 @@ #include "error.h" #include "block_alloc.h" -RCSID("$Id: callback.c,v 1.16 1999/01/31 09:01:41 hubbe Exp $"); +RCSID("$Id: callback.c,v 1.17 1999/05/02 08:11:33 hubbe Exp $"); struct callback_list fork_child_callback; @@ -172,10 +172,10 @@ void call_callback(struct callback_list *lst, void *arg) } /* Add a callback to the linked list pointed to by ptr. */ -struct callback *add_to_callback(struct callback_list *lst, - callback_func call, - void *arg, - callback_func free_func) +struct callback *debug_add_to_callback(struct callback_list *lst, + callback_func call, + void *arg, + callback_func free_func) { struct callback *l; l=alloc_callback(); @@ -183,6 +183,8 @@ struct callback *add_to_callback(struct callback_list *lst, l->arg=arg; l->free_func=free_func; + DO_IF_DMALLOC( if(l->free_func == free) l->free_func=dmalloc_free; ) + l->next=lst->callbacks; lst->callbacks=l; @@ -196,6 +198,7 @@ struct callback *add_to_callback(struct callback_list *lst, */ void *remove_callback(struct callback *l) { + dmalloc_unregister(l,1); l->call=0; l->free_func=0; return l->arg; @@ -221,18 +224,3 @@ void cleanup_callbacks(void) free_all_callback_blocks(); } - -void count_memory_in_callbacks(INT32 *num_, INT32 *size_) -{ - INT32 num=0, size=0; - struct callback_block *tmp; - struct callback *tmp2; - for(tmp=callback_blocks;tmp;tmp=tmp->next) - { - num+=CALLBACK_CHUNK; - size+=sizeof(struct callback_block); - } - for(tmp2=free_callbacks;tmp2;tmp2=tmp2->next) num--; - *num_=num; - *size_=size; -} diff --git a/src/callback.h b/src/callback.h index 9a6c241e9612ec3f6a129fab64aaaf584247227d..850cdfc0ce79d5d386790591c67668e1d3dfd8dd 100644 --- a/src/callback.h +++ b/src/callback.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: callback.h,v 1.7 1998/03/28 15:38:18 grubba Exp $ + * $Id: callback.h,v 1.8 1999/05/02 08:11:34 hubbe Exp $ */ #ifndef CALLBACK_H #define CALLBACK_H @@ -26,16 +26,17 @@ typedef void (*callback_func)(struct callback *, void *,void *); /* Prototypes begin here */ struct callback; -struct callback_block; void call_callback(struct callback_list *lst, void *arg); -struct callback *add_to_callback(struct callback_list *lst, - callback_func call, - void *arg, - callback_func free_func); +struct callback *debug_add_to_callback(struct callback_list *lst, + callback_func call, + void *arg, + callback_func free_func); void *remove_callback(struct callback *l); void free_callback_list(struct callback_list *lst); void cleanup_callbacks(void); -void count_memory_in_callbacks(INT32 *num_, INT32 *size_); /* Prototypes end here */ +#define add_to_callback(LST,CALL,ARG,FF) \ + dmalloc_touch(struct callback *,debug_add_to_callback((LST),(CALL),(ARG),(FF))) + #endif diff --git a/src/configure.in b/src/configure.in index 8cb57974ad0d31ceca2db74be6f6f3b096c6e7c7..f3a2dd4498fdaef22eb8ad383099360cda67376f 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1,4 +1,4 @@ -AC_REVISION("$Id: configure.in,v 1.280 1999/04/30 07:22:17 hubbe Exp $") +AC_REVISION("$Id: configure.in,v 1.281 1999/05/02 08:11:35 hubbe Exp $") AC_INIT(interpret.c) AC_CONFIG_HEADER(machine.h) @@ -161,7 +161,8 @@ fi CC="$SMARTLINK $REALCC" pike_cv_prog_CC="$CC" -AC_SUBST(SMARTLINK REALCC) +AC_SUBST(SMARTLINK) +AC_SUBST(REALCC) export REALCC SMARTLINK ############################################################################# diff --git a/src/constants.c b/src/constants.c index 7aaac6f47b94013c36375b8da73d8a173498c1e5..e5f405df4ad32702c0f858a4e930f6b655835bfc 100644 --- a/src/constants.c +++ b/src/constants.c @@ -15,9 +15,8 @@ #include "error.h" #include "block_alloc.h" -RCSID("$Id: constants.c,v 1.17 1999/04/15 04:08:09 hubbe Exp $"); +RCSID("$Id: constants.c,v 1.18 1999/05/02 08:11:37 hubbe Exp $"); -static INT32 num_callable=0; static struct mapping *builtin_constants = 0; struct mapping *get_builtin_constants(void) @@ -64,13 +63,10 @@ void add_global_program(char *name, struct program *p) low_add_constant(name, &s); } -#undef INIT_BLOCK -#define INIT_BLOCK(X) num_callable++ #undef EXIT_BLOCK #define EXIT_BLOCK(X) do { \ free_string(X->type); \ free_string(X->name); \ - num_callable--; \ }while(0) BLOCK_ALLOC(callable,128) @@ -169,8 +165,3 @@ void cleanup_added_efuns(void) } #endif } -void count_memory_in_callables(INT32 *num_, INT32 *size_) -{ - *num_=num_callable; - *size_=num_callable*sizeof(struct callable); -} diff --git a/src/dmalloc.h b/src/dmalloc.h index 5d0626b43e62a7f89b87ee6f1b3f0335f4a3612f..b2e42439e23bd79fec13ffd2d2b6da90f8727221 100644 --- a/src/dmalloc.h +++ b/src/dmalloc.h @@ -1,5 +1,5 @@ /* - * $Id: dmalloc.h,v 1.10 1999/03/19 11:39:29 hubbe Exp $ + * $Id: dmalloc.h,v 1.11 1999/05/02 08:11:38 hubbe Exp $ */ extern char *debug_xalloc(long); @@ -16,17 +16,21 @@ void low_add_marks_to_memhdr(struct memhdr *to, extern int verbose_debug_malloc; extern int verbose_debug_exit; +extern void dmalloc_register(void *, int,char *, int); +extern int dmalloc_unregister(void *, int); extern void *debug_malloc(size_t, const char *, int); extern void *debug_calloc(size_t, size_t, const char *, int); extern void *debug_realloc(void *, size_t, const char *, int); -extern void debug_free(void *, const char *, int); +extern void debug_free(void *, const char *, int,int); extern char *debug_strdup(const char *, const char *, int); extern void reset_debug_malloc(void); +extern void dmalloc_free(void *p); void *debug_malloc_update_location(void *,const char *, int); #define malloc(x) debug_malloc((x), __FILE__, __LINE__) #define calloc(x, y) debug_calloc((x), (y), __FILE__, __LINE__) #define realloc(x, y) debug_realloc((x), (y), __FILE__, __LINE__) -#define free(x) debug_free((x), __FILE__, __LINE__) +#define free(x) debug_free((x), __FILE__, __LINE__,0) +#define dmfree(x) debug_free((x),__FILE__,__LINE__,1) #define strdup(x) debug_strdup((x), __FILE__, __LINE__) #define DO_IF_DMALLOC(X) X #define debug_malloc_touch(X) debug_malloc_update_location((X),__FILE__,__LINE__) @@ -34,7 +38,17 @@ void *debug_malloc_update_location(void *,const char *, int); #define xalloc(X) ((char *)debug_malloc_touch(debug_xalloc(X))) void debug_malloc_dump_references(void *x); #define dmalloc_touch(TYPE,X) ((TYPE)debug_malloc_update_location((X),__FILE__,__LINE__)) + +#define DMALLOC_LINE_ARGS ,char * dmalloc_file, int dmalloc_line +#define DMALLOC_POS ,__FILE__,__LINE__ +#define DMALLOC_PROXY_ARGS ,dmalloc_file,dmalloc_line +void *dmalloc_accept_leak(void *); #else +#define dmfree(X) free((X)) +#define dmalloc_accept_leak(X) (X) +#define DMALLOC_LINE_ARGS +#define DMALLOC_POS +#define DMALLOC_PROXY_ARGS #define debug_malloc_dump_references(X) #define xalloc debug_xalloc #define dbm_main main @@ -43,4 +57,7 @@ void debug_malloc_dump_references(void *x); #define debug_malloc_touch(X) #define debug_malloc_pass(X) (X) #define dmalloc_touch(TYPE,X) (X) +#define dmalloc_register(X,Y,Z) +#define dmalloc_unregister(X,Y) +#define debug_free(X,Y,Z,Q) free((X)) #endif diff --git a/src/error.c b/src/error.c index bf52817b66187598f656e5834b3fa55dd21d53ef..a98e5315552e905ef732fac2a26ddd1dede557f9 100644 --- a/src/error.c +++ b/src/error.c @@ -19,7 +19,7 @@ #include "module_support.h" #include "threads.h" -RCSID("$Id: error.c,v 1.34 1999/04/17 13:47:16 grubba Exp $"); +RCSID("$Id: error.c,v 1.35 1999/05/02 08:11:39 hubbe Exp $"); #undef ATTRIBUTE #define ATTRIBUTE(X) @@ -80,14 +80,11 @@ void pike_throw(void) ATTRIBUTE((noreturn)) while(fp != recoveries->fp) { - struct pike_frame *tmp=fp; #ifdef PIKE_DEBUG if(!fp) fatal("Popped out of stack frames.\n"); #endif - fp = tmp->next; - tmp->next=0; - free_pike_frame(tmp); + POP_PIKE_FRAME(); } pop_n_elems(sp - evaluator_stack - recoveries->sp); @@ -483,7 +480,7 @@ void permission_error( char *func, struct svalue *base_sp, int args, char *permission_type, - char *desc, ...) ATTRIBUTE((noreturn, format(printf, 2, 3))) + char *desc, ...) ATTRIBUTE((noreturn, format(printf, 5, 6))) { INIT_ERROR(permission); ERROR_STRUCT(permission,o)->permission_type= diff --git a/src/error.h b/src/error.h index a6de3eb4b57bb1c213d05ea32a9d3c6433a14935..75c59a77c598654fbc4fa385e415fc65ebddc5bd 100644 --- a/src/error.h +++ b/src/error.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: error.h,v 1.35 1999/04/10 00:42:00 hubbe Exp $ + * $Id: error.h,v 1.36 1999/05/02 08:11:40 hubbe Exp $ */ #ifndef ERROR_H #define ERROR_H @@ -103,6 +103,7 @@ extern int throw_severity; OED_FPRINTF((stderr, "SET_ONERROR(%p, %p, %p) %s:%d\n", \ &(X), (Y), (void *)(Z), __FILE__, __LINE__)); \ X.func=(error_call)(Y); \ + DO_IF_DMALLOC( if( X.func == free ) X.func=dmalloc_free;) \ X.arg=(void *)(Z); \ if(!recoveries) break; \ X.previous=recoveries->onerror; \ @@ -172,6 +173,7 @@ void check_recovery_context(void); JMP_BUF *init_recovery(JMP_BUF *r DEBUG_LINE_ARGS); void pike_throw(void) ATTRIBUTE((noreturn)); void push_error(char *description); +void low_error(char *buf); void va_error(const char *fmt, va_list args) ATTRIBUTE((noreturn)); void new_error(const char *name, const char *text, struct svalue *oldsp, INT32 args, const char *file, int line) ATTRIBUTE((noreturn)); @@ -217,6 +219,11 @@ void resource_error( char *resource_type, long howmuch, char *desc, ...) ATTRIBUTE((noreturn,format (printf, 6, 7))); +void permission_error( + char *func, + struct svalue *base_sp, int args, + char *permission_type, + char *desc, ...) ATTRIBUTE((noreturn, format(printf, 5, 6))); void init_error(void); void cleanup_error(void); /* Prototypes end here */ diff --git a/src/gc.c b/src/gc.c index 36a3886dc17981f65d229ffaeb270fac858ebd7a..a51d490ada4335d0a63bc062abec0ffb9776e662 100644 --- a/src/gc.c +++ b/src/gc.c @@ -21,12 +21,13 @@ struct callback *gc_evaluator_callback=0; #include "pike_types.h" #include "time_stuff.h" #include "constants.h" +#include "block_alloc.h" #include "gc.h" #include "main.h" #include <math.h> -RCSID("$Id: gc.c,v 1.41 1999/03/17 21:49:24 hubbe Exp $"); +RCSID("$Id: gc.c,v 1.42 1999/05/02 08:11:41 hubbe Exp $"); /* Run garbage collect approximate every time we have * 20 percent of all arrays, objects and programs is @@ -50,7 +51,7 @@ static double objects_freed = 0.0; struct callback_list gc_callbacks; -struct callback *add_gc_callback(callback_func call, +struct callback *debug_add_gc_callback(callback_func call, void *arg, callback_func free_func) { @@ -68,65 +69,17 @@ struct marker #endif INT32 flags; struct marker *next; - void *marked; + void *data; }; -struct marker_chunk -{ - struct marker_chunk *next; - struct marker markers[MARKER_CHUNK_SIZE]; -}; - -static struct marker_chunk *chunk=0; -static int markers_left_in_chunk=0; - -static struct marker *new_marker(void) -{ - if(!markers_left_in_chunk) - { - struct marker_chunk *m; - m=(struct marker_chunk *)xalloc(sizeof(struct marker_chunk)); - m->next=chunk; - chunk=m; - markers_left_in_chunk=MARKER_CHUNK_SIZE; - } - markers_left_in_chunk--; - - return chunk->markers + markers_left_in_chunk; -} - -static struct marker **hash=0; -static unsigned long hashsize=0; - -static struct marker *getmark(void *a) -{ - unsigned long hashval; - struct marker *m; - - hashval=(unsigned long)a; - hashval%=hashsize; - +#undef INIT_BLOCK #ifdef PIKE_DEBUG - if(hashval >= hashsize) - fatal("Compiler has buggy modulo operator.\n"); -#endif - - for(m=hash[hashval];m;m=m->next) - if(m->marked == a) - return m; - - m=new_marker(); - m->marked=a; - m->refs=0; -#ifdef PIKE_DEBUG - m->xrefs=0; +#define INIT_BLOCK(X) (X)->flags=(X)->refs=(X)->xrefs=0 +#else +#define INIT_BLOCK(X) (X)->flags=(X)->refs=0 #endif - m->flags=0; - m->next=hash[hashval]; - hash[hashval]=m; - return m; -} +PTR_HASH_ALLOC(marker,MARKER_CHUNK_SIZE) #ifdef PIKE_DEBUG @@ -465,11 +418,12 @@ INT32 gc_check(void *a) return 0; } #endif - return add_ref(getmark(a)); + return add_ref(get_marker(a)); } static void init_gc(void) { +#if 0 INT32 tmp3; /* init hash , hashsize will be a prime between num_objects/8 and * num_objects/4, this will assure that no re-hashing is needed. @@ -484,10 +438,14 @@ static void init_gc(void) hash=(struct marker **)xalloc(sizeof(struct marker **)*hashsize); MEMSET((char *)hash,0,sizeof(struct marker **)*hashsize); markers_left_in_chunk=0; +#else + init_marker_hash(); +#endif } static void exit_gc(void) { +#if 0 struct marker_chunk *m; /* Free hash table */ free((char *)hash); @@ -496,6 +454,16 @@ static void exit_gc(void) chunk=m->next; free((char *)m); } +#else +#ifdef DO_PIKE_CLEANUP + int e=0; + struct marker *h; + for(e=0;e<marker_hash_table_size;e++) + while(marker_hash_table[e]) + remove_marker(marker_hash_table[e]->data); +#endif + exit_marker_hash(); +#endif } #ifdef PIKE_DEBUG @@ -537,7 +505,7 @@ void locate_references(void *a) int gc_is_referenced(void *a) { struct marker *m; - m=getmark(a); + m=get_marker(a); #ifdef PIKE_DEBUG if(m->refs + m->xrefs > *(INT32 *)a || (!(m->refs < *(INT32 *)a) && m->xrefs) ) @@ -577,7 +545,7 @@ int gc_external_mark(void *a) } return 0; } - m=getmark(a); + m=get_marker(a); m->xrefs++; m->flags|=GC_XREFERENCED; gc_is_referenced(a); @@ -588,7 +556,7 @@ int gc_external_mark(void *a) int gc_mark(void *a) { struct marker *m; - m=getmark(a); + m=get_marker(a); if(m->flags & GC_REFERENCED) { @@ -602,7 +570,7 @@ int gc_mark(void *a) int gc_do_free(void *a) { struct marker *m; - m=getmark(a); + m=get_marker(a); #ifdef PIKE_DEBUG if( !(m->flags & GC_REFERENCED) && m->flags & GC_XREFERENCED ) { diff --git a/src/gc.h b/src/gc.h index e29ecfee223d87700450e52321f233e522e98987..a879ae136f9d04b9c05d6a5be2b5b28ef06b88fb 100644 --- a/src/gc.h +++ b/src/gc.h @@ -1,5 +1,5 @@ /* - * $Id: gc.h,v 1.21 1998/12/16 07:49:36 hubbe Exp $ + * $Id: gc.h,v 1.22 1999/05/02 08:11:42 hubbe Exp $ */ #ifndef GC_H #define GC_H @@ -28,7 +28,7 @@ extern void *gc_svalue_location; #endif /* Prototypes begin here */ -struct callback *add_gc_callback(callback_func call, +struct callback *debug_add_gc_callback(callback_func call, void *arg, callback_func free_func); struct marker; @@ -63,4 +63,7 @@ void do_gc(void); #endif +#define add_gc_callback(X,Y,Z) \ + dmalloc_touch(struct callback *,debug_add_gc_callback((X),(Y),(Z))) + #endif diff --git a/src/interpret.c b/src/interpret.c index e59bfe2349b2a5252bd275c3bb6b162d8a50e1a2..2d9fa132df0e928e30650aade1726c85a902de19 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: interpret.c,v 1.121 1999/04/17 13:48:47 grubba Exp $"); +RCSID("$Id: interpret.c,v 1.122 1999/05/02 08:11:43 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -186,6 +186,7 @@ use_malloc: if(!spcb) { spcb=add_gc_callback(gc_check_stack_callback,0,0); + dmalloc_accept_leak(spcb); } } #endif @@ -790,7 +791,7 @@ void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2) { struct program *p; struct reference *ref; - struct pike_frame *new_frame=alloc_pike_frame(); + struct pike_frame *new_frame; struct identifier *function; if(fun<0) @@ -804,6 +805,9 @@ void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2) check_mark_stack(256); check_c_stack(8192); + new_frame=alloc_pike_frame(); + debug_malloc_touch(new_frame); + #ifdef PIKE_DEBUG if(d_flag>2) do_debug(); #endif @@ -914,6 +918,7 @@ void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2) switch(function->identifier_flags & (IDENTIFIER_FUNCTION | IDENTIFIER_CONSTANT)) { case IDENTIFIER_C_FUNCTION: + debug_malloc_touch(fp); fp->num_args=args; new_frame->num_locals=args; check_threads_etc(); @@ -923,6 +928,7 @@ void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2) case IDENTIFIER_CONSTANT: { struct svalue *s=fp->context.prog->constants+function->func.offset; + debug_malloc_touch(fp); if(s->type == T_PROGRAM) { struct object *tmp; @@ -939,6 +945,7 @@ void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2) case 0: { + debug_malloc_touch(fp); if(sp-save_sp-args<=0) { /* Create an extra svalue for tail recursion style call */ @@ -1109,6 +1116,7 @@ static int o_catch(unsigned char *pc) { JMP_BUF tmp; struct svalue *expendible=fp->expendible; + debug_malloc_touch(fp); if(SETJMP(tmp)) { *sp=throw_value; @@ -1328,12 +1336,7 @@ void cleanup_interpret(void) #endif while(fp) - { - struct pike_frame *tmp=fp; - fp=tmp->next; - tmp->next=0; - free_pike_frame(tmp); - } + POP_PIKE_FRAME(); #ifdef PIKE_DEBUG for(e=0;e<BACKLOG;e++) @@ -1372,6 +1375,13 @@ void cleanup_interpret(void) void really_clean_up_interpret(void) { #ifdef DO_PIKE_CLEANUP +#if 0 + struct pike_frame_block *p; + int e; + for(p=pike_frame_blocks;p;p=p->next) + for(e=0;e<128;e++) + debug_malloc_dump_references( p->x + e); +#endif free_all_pike_frame_blocks(); #endif } diff --git a/src/interpret.h b/src/interpret.h index cd6454a1217ebed91a427403b825ca957d68ceb4..1a9af86c62b303fbd53583535a9a01aa975e28f8 100644 --- a/src/interpret.h +++ b/src/interpret.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: interpret.h,v 1.30 1999/04/15 19:12:50 hubbe Exp $ + * $Id: interpret.h,v 1.31 1999/05/02 08:11:44 hubbe Exp $ */ #ifndef INTERPRET_H #define INTERPRET_H @@ -102,6 +102,7 @@ struct pike_frame really_free_pike_frame(fp); \ }else{ \ DO_IF_DEBUG(if( fp->locals+fp->num_locals>sp) fatal("Stack failure in POP_PIKE_FRAME!\n")); \ + debug_malloc_touch(fp); \ if(fp->num_locals) \ { \ struct svalue *s=(struct svalue *)xalloc(sizeof(struct svalue)* \ diff --git a/src/interpreter.h b/src/interpreter.h index 156f287a1b783a09674b639a777d664784b3e528..566d522fd469c3b87b82d2030df2a7f37bc13e13 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -22,6 +22,7 @@ static int eval_instruction(unsigned char *pc) { unsigned INT32 accumulator=0,instr, prefix=0; + debug_malloc_touch(fp); while(1) { fp->pc = pc; diff --git a/src/modules/call_out/call_out.c b/src/modules/call_out/call_out.c index 0a6bfbd53dd556e53199d09412dd01df303f3471..63f6b48c268f58992c1f33429c4f389397121800 100644 --- a/src/modules/call_out/call_out.c +++ b/src/modules/call_out/call_out.c @@ -6,7 +6,7 @@ /**/ #include "global.h" #include "config.h" -RCSID("$Id: call_out.c,v 1.26 1999/04/24 13:43:28 grubba Exp $"); +RCSID("$Id: call_out.c,v 1.27 1999/05/02 08:12:32 hubbe Exp $"); #include "array.h" #include "dynamic_buffer.h" #include "object.h" @@ -453,13 +453,15 @@ void f_call_out(INT32 args) if(!mem_callback) mem_callback=add_memory_usage_callback(count_memory_in_call_outs,0,0); + #ifdef PIKE_DEBUG if(!verify_call_out_callback) { verify_call_out_callback=add_to_callback(& do_debug_callbacks, do_verify_call_outs, 0, 0); - add_gc_callback(mark_call_outs, 0, 0); + dmalloc_accept_leak(verify_call_out_callback); + dmalloc_accept_leak(add_gc_callback(mark_call_outs, 0, 0)); } #endif @@ -730,4 +732,21 @@ void pike_module_init(void) void pike_module_exit(void) { free_all_call_outs(); +#ifdef DO_PIKE_CLEANUP + if(mem_callback) + { + remove_callback(mem_callback); + mem_callback=0; + } + if(verify_call_out_callback) + { + remove_callback(verify_call_out_callback); + verify_call_out_callback=0; + } + if(call_out_backend_callback) + { + remove_callback(call_out_backend_callback); + call_out_backend_callback=0; + } +#endif } diff --git a/src/modules/files/file.c b/src/modules/files/file.c index 345a0c46a95866bc98a584e63d8a42ed9a639639..271d07c52ff747323113e6c5306a71197d1b358d 100644 --- a/src/modules/files/file.c +++ b/src/modules/files/file.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: file.c,v 1.151 1999/04/20 20:35:01 grubba Exp $"); +RCSID("$Id: file.c,v 1.152 1999/05/02 08:12:48 hubbe Exp $"); #include "fdlib.h" #include "interpret.h" #include "svalue.h" @@ -2627,10 +2627,10 @@ void pike_module_init(void) #endif #ifdef PIKE_DEBUG - add_to_callback(&do_debug_callbacks, - check_static_file_data, - 0, - 0); + dmalloc_accept_leak(add_to_callback(&do_debug_callbacks, + check_static_file_data, + 0, + 0)); #endif } diff --git a/src/modules/system/system.c b/src/modules/system/system.c index 293bd47aae6cd60e321e5178c129d267d63222e4..c5dc632b90b10dc6bbc8e1cc55873c28f2e6d402 100644 --- a/src/modules/system/system.c +++ b/src/modules/system/system.c @@ -1,5 +1,5 @@ /* - * $Id: system.c,v 1.69 1999/04/16 20:40:57 grubba Exp $ + * $Id: system.c,v 1.70 1999/05/02 08:13:05 hubbe Exp $ * * System-call module for Pike * @@ -15,7 +15,7 @@ #include "system_machine.h" #include "system.h" -RCSID("$Id: system.c,v 1.69 1999/04/16 20:40:57 grubba Exp $"); +RCSID("$Id: system.c,v 1.70 1999/05/02 08:13:05 hubbe Exp $"); #ifdef HAVE_WINSOCK_H #include <winsock.h> #endif @@ -1186,7 +1186,8 @@ void pike_module_init(void) init_passwd(); #ifdef GETHOSTBYNAME_MUTEX_EXISTS - add_to_callback(& fork_child_callback, cleanup_after_fork, 0, 0); + dmalloc_accept_leak(add_to_callback(& fork_child_callback, + cleanup_after_fork, 0, 0)); #endif #ifdef __NT__ diff --git a/src/pike_memory.c b/src/pike_memory.c index f5bb736d8043a341b933f3da1ac8a76d2f0cb636..a4c00de80b1526a76432709b1414ec8b55178dcf 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.36 1999/04/01 17:21:07 hubbe Exp $"); +RCSID("$Id: pike_memory.c,v 1.37 1999/05/02 08:11:46 hubbe Exp $"); /* strdup() is used by several modules, so let's provide it */ #ifndef HAVE_STRDUP @@ -622,7 +622,7 @@ static MUTEX_T debug_malloc_mutex; #undef main static void add_location(struct memhdr *mh, int locnum); -static struct memhdr *find_memhdr(void *p); +static struct memhdr *my_find_memhdr(void *, int); #include "block_alloc.h" @@ -630,10 +630,9 @@ int verbose_debug_malloc = 0; int verbose_debug_exit = 1; int debug_malloc_check_all = 0; -#define HSIZE 1109891 #define LHSIZE 1109891 #define FLSIZE 8803 -#define DEBUG_MALLOC_PAD 8 +#define DEBUG_MALLOC_PAD 32 #define FREE_DELAY 4096 #define MAX_UNFREE_MEM 1024*1024*32 @@ -650,6 +649,11 @@ struct fileloc int number; }; + +/* Hepp, we cannot do dmalloc on dmalloc structures... */ +#undef DO_IF_DMALLOC +#define DO_IF_DMALLOC(X) + BLOCK_ALLOC(fileloc, 4090) struct memloc @@ -660,22 +664,24 @@ struct memloc int times; }; +#define MEM_PADDED 1 + BLOCK_ALLOC(memloc, 16382) struct memhdr { struct memhdr *next; long size; + int flags; void *data; struct memloc *locations; }; static struct fileloc *flhash[FLSIZE]; static struct memloc *mlhash[LHSIZE]; -static struct memhdr *hash[HSIZE]; static struct memhdr no_leak_memlocs; -static int file_location_number=0; +static int file_location_number=1; #if DEBUG_MALLOC_PAD - 0 > 0 char *do_pad(char *mem, long size) @@ -686,12 +692,20 @@ char *do_pad(char *mem, long size) /* fprintf(stderr,"Padding %p(%d) %ld\n",mem, size, q); */ #if 1 - for(e=0;e< DEBUG_MALLOC_PAD; e++) + for(e=0;e< DEBUG_MALLOC_PAD; e+=4) { - char tmp=q|1; + char tmp; q=(q<<13) ^ ~(q>>5); - mem[e-DEBUG_MALLOC_PAD] = tmp; - mem[size+e] = tmp; + +#define BLORG(X,Y) \ + tmp=(Y); \ + mem[e+(X)-DEBUG_MALLOC_PAD] = tmp; \ + mem[size+e+(X)] = tmp; + + BLORG(0, (q) | 1) + BLORG(1, (q >> 5) | 1) + BLORG(2, (q >> 10) | 1) + BLORG(3, (q >> 15) | 1) } #endif return mem; @@ -705,6 +719,7 @@ void check_pad(struct memhdr *mh, int freeok) long size=mh->size; if(out_biking) return; + if(!(mh->flags & MEM_PADDED)) return; if(size < 0) { if(!freeok) @@ -720,24 +735,37 @@ void check_pad(struct memhdr *mh, int freeok) /* fprintf(stderr,"Checking %p(%d) %ld\n",mem, size, q); */ #if 1 - for(e=0;e< DEBUG_MALLOC_PAD; e++) + for(e=0;e< DEBUG_MALLOC_PAD; e+=4) { - char tmp=q|1; + char tmp; q=(q<<13) ^ ~(q>>5); - if(mem[e-DEBUG_MALLOC_PAD] != tmp) - { - out_biking=1; - fprintf(stderr,"Pre-padding overwritten for block at %p (size %ld) (e=%ld %d!=%d)!\n",mem, size, e, tmp, mem[e-DEBUG_MALLOC_PAD]); - describe(mem); - abort(); - } - if(mem[size+e] != tmp) - { - out_biking=1; - fprintf(stderr,"Post-padding overwritten for block at %p (size %ld) (e=%ld %d!=%d)!\n",mem, size, e, tmp, mem[size+e]); - describe(mem); - abort(); + +#undef BLORG +#define BLORG(X,Y) \ + tmp=(Y); \ + if(mem[e+(X)-DEBUG_MALLOC_PAD] != tmp) \ + { \ + out_biking=1; \ + fprintf(stderr,"Pre-padding overwritten for " \ + "block at %p (size %ld) (e=%ld %d!=%d)!\n", \ + mem, size, e, tmp, mem[e-DEBUG_MALLOC_PAD]); \ + describe(mem); \ + abort(); \ + } \ + if(mem[size+e+(X)] != tmp) \ + { \ + out_biking=1; \ + fprintf(stderr,"Post-padding overwritten for " \ + "block at %p (size %ld) (e=%ld %d!=%d)!\n", \ + mem, size, e, tmp, mem[size+e]); \ + describe(mem); \ + abort(); \ } + + BLORG(0, (q) | 1) + BLORG(1, (q >> 5) | 1) + BLORG(2, (q >> 10) | 1) + BLORG(3, (q >> 15) | 1) } #endif } @@ -796,7 +824,7 @@ void low_add_marks_to_memhdr(struct memhdr *to, void add_marks_to_memhdr(struct memhdr *to, void *ptr) { - low_add_marks_to_memhdr(to,find_memhdr(ptr)); + low_add_marks_to_memhdr(to,my_find_memhdr(ptr,0)); } static inline unsigned long lhash(struct memhdr *m, int locnum) @@ -812,7 +840,7 @@ static inline unsigned long lhash(struct memhdr *m, int locnum) #undef INIT_BLOCK #undef EXIT_BLOCK -#define INIT_BLOCK(X) X->locations=0 +#define INIT_BLOCK(X) X->locations=0; X->flags=0; #define EXIT_BLOCK(X) do { \ struct memloc *ml; \ while((ml=X->locations)) \ @@ -825,7 +853,7 @@ static inline unsigned long lhash(struct memhdr *m, int locnum) } \ }while(0) -BLOCK_ALLOC(memhdr,16382) +PTR_HASH_ALLOC(memhdr,16382) #undef INIT_BLOCK #undef EXIT_BLOCK @@ -834,17 +862,18 @@ BLOCK_ALLOC(memhdr,16382) #define EXIT_BLOCK(X) -static struct memhdr *find_memhdr(void *p) + +static struct memhdr *my_find_memhdr(void *p, int already_gone) { - struct memhdr *mh,**prev; - unsigned long h; + struct memhdr *mh; #if DEBUG_MALLOC_PAD - 0 > 0 if(debug_malloc_check_all) { - for(h=0;h<HSIZE;h++) + long h; + for(h=0;h<memhdr_hash_table_size;h++) { - for(mh=hash[h]; mh; mh=mh->next) + for(mh=memhdr_hash_table[h]; mh; mh=mh->next) { check_pad(mh,1); } @@ -852,20 +881,11 @@ static struct memhdr *find_memhdr(void *p) } #endif - h=(long)p; - h%=HSIZE; - for(prev=hash+h; (mh=*prev); prev=&mh->next) - { - if(mh->data==p) - { - *prev=mh->next; - mh->next=hash[h]; - hash[h]=mh; + if((mh=find_memhdr(p))) + if(!already_gone) check_pad(mh,0); - return mh; - } - } - return NULL; + + return mh; } @@ -924,43 +944,47 @@ static void add_location(struct memhdr *mh, int locnum) mlhash[l]=ml; } -static void make_memhdr(void *p, int s, int locnum) +static struct memhdr *low_make_memhdr(void *p, int s, int locnum) { - struct memhdr *mh=alloc_memhdr(); + struct memhdr *mh=get_memhdr(p); struct memloc *ml=alloc_memloc(); unsigned long l=lhash(mh,locnum); - unsigned long h=(long)p; - h%=HSIZE; - - mh->next=hash[h]; - mh->data=p; + mh->size=s; mh->locations=ml; ml->locnum=locnum; ml->next=0; ml->times=1; - hash[h]=mh; mlhash[l]=ml; + + return mh; +} + +void dmalloc_register(void *p, int s, char *file, int line) +{ + low_make_memhdr(p,s,location_number(file, line)); } -static int remove_memhdr(void *p, int already_gone) +void *dmalloc_accept_leak(void *p) { - struct memhdr **prev,*mh; - unsigned long h=(long)p; - h%=HSIZE; - for(prev=hash+h;(mh=*prev);prev=&(mh->next)) + if(p) { - if(mh->data==p) - { - if(mh->size < 0) mh->size=~mh->size; - if(!already_gone) check_pad(mh,0); + struct memhdr *mh; + if((mh=my_find_memhdr(p,0))) add_location(mh, 0); + } + return p; +} - *prev=mh->next; - low_add_marks_to_memhdr(&no_leak_memlocs, mh); - really_free_memhdr(mh); - - return 1; - } +int dmalloc_unregister(void *p, int already_gone) +{ + struct memhdr *mh=find_memhdr(p); + if(mh) + { + if(mh->size < 0) mh->size=~mh->size; + if(!already_gone) check_pad(mh,0); + low_add_marks_to_memhdr(&no_leak_memlocs, mh); + remove_memhdr(p); + return 1; } return 0; } @@ -975,7 +999,7 @@ void *debug_malloc(size_t s, const char *fn, int line) if(m) { m=do_pad(m, s); - make_memhdr(m, s, location_number(fn,line)); + low_make_memhdr(m, s, location_number(fn,line))->flags|=MEM_PADDED; } if(verbose_debug_malloc) @@ -1003,16 +1027,13 @@ void *debug_realloc(void *p, size_t s, const char *fn, int line) char *m,*base; mt_lock(&debug_malloc_mutex); - base=find_memhdr(p) ? (void *)(((char *)p)-DEBUG_MALLOC_PAD): p; + base=my_find_memhdr(p,0) ? (void *)(((char *)p)-DEBUG_MALLOC_PAD): p; m=realloc(base, s+DEBUG_MALLOC_PAD*2); if(m) { m=do_pad(m, s); - if(m != base) - { - if(p) remove_memhdr(p,1); - make_memhdr(m, s, location_number(fn,line)); - } + if(p) dmalloc_unregister(p,1); + low_make_memhdr(m, s, location_number(fn,line))->flags|=MEM_PADDED; } if(verbose_debug_malloc) fprintf(stderr, "realloc(%p,%d) => %p (%s:%d)\n", p, s, m, fn,line); @@ -1020,14 +1041,22 @@ void *debug_realloc(void *p, size_t s, const char *fn, int line) return m; } -void debug_free(void *p, const char *fn, int line) +void debug_free(void *p, const char *fn, int line, int mustfind) { struct memhdr *mh; if(!p) return; mt_lock(&debug_malloc_mutex); if(verbose_debug_malloc) fprintf(stderr, "free(%p) (%s:%d)\n", p, fn,line); - if(!exiting && (mh=find_memhdr(p))) + mh=my_find_memhdr(p,0); + + if(!mh && mustfind && p) + { + fprintf(stderr,"Lost track of a mustfind memory block: %p!\n",p); + abort(); + } + + if(!exiting && mh) { void *p2; MEMSET(p, 0x55, mh->size); @@ -1039,14 +1068,41 @@ void debug_free(void *p, const char *fn, int line) blocks_to_free_ptr%=FREE_DELAY; p2=blocks_to_free[blocks_to_free_ptr]; blocks_to_free[blocks_to_free_ptr]=p; - p=p2; + if((p=p2)) + { + mh=my_find_memhdr(p,1); + if(!mh) + { + fprintf(stderr,"Lost track of a freed memory block: %p!\n",p); + abort(); + } + }else{ + mh=0; + } } } - if(remove_memhdr(p,0)) p=((char *)p) - DEBUG_MALLOC_PAD; - free(p); + + if(mh) + { + free( ((char *)p) - DEBUG_MALLOC_PAD ); + if(!dmalloc_unregister(p,1)) + { + fprintf(stderr,"Lost track of a memory block (2): %p!\n",p); + abort(); + } + } + else + { + free(p); + } mt_unlock(&debug_malloc_mutex); } +void dmalloc_free(void *p) +{ + debug_free(p, __FILE__, __LINE__, 0); +} + char *debug_strdup(const char *s, const char *fn, int line) { char *m; @@ -1080,7 +1136,7 @@ void dump_memhdr_locations(struct memhdr *from, void debug_malloc_dump_references(void *x) { - dump_memhdr_locations(find_memhdr(x),0); + dump_memhdr_locations(my_find_memhdr(x,0),0); } void cleanup_memhdrs() @@ -1092,7 +1148,7 @@ void cleanup_memhdrs() void *p; if((p=blocks_to_free[h])) { - if(remove_memhdr(p,0)) p=((char *)p) - DEBUG_MALLOC_PAD; + if(dmalloc_unregister(p,0)) p=((char *)p) - DEBUG_MALLOC_PAD; free(p); blocks_to_free[h]=0; } @@ -1102,15 +1158,20 @@ void cleanup_memhdrs() if(verbose_debug_exit) { int first=1; - for(h=0;h<HSIZE;h++) + for(h=0;h<memhdr_hash_table_size;h++) { struct memhdr *m; - for(m=hash[h];m;m=m->next) + for(m=memhdr_hash_table[h];m;m=m->next) { struct memhdr *tmp; struct memloc *l; void *p=m->data; + for(l=m->locations;l;l=l->next) + if(!l->locnum) + break; + if(l) continue; /* acceptable leak */ + mt_unlock(&debug_malloc_mutex); if(first) { @@ -1126,7 +1187,7 @@ void cleanup_memhdrs() mt_lock(&debug_malloc_mutex); /* Now we must reassure 'm' */ - for(tmp=hash[h];tmp;tmp=tmp->next) + for(tmp=memhdr_hash_table[h];tmp;tmp=tmp->next) if(m==tmp) break; @@ -1157,7 +1218,14 @@ void cleanup_memhdrs() int main(int argc, char *argv[]) { extern int dbm_main(int, char **); + +#if DEBUG_MALLOC_PAD & 3 + fprintf(stderr,"DEBUG_MALLOC_PAD not dividable by four!\n"); + exit(99); +#endif + mt_init(&debug_malloc_mutex); + init_memhdr_hash(); return dbm_main(argc, argv); } @@ -1166,7 +1234,7 @@ void * debug_malloc_update_location(void *p,const char *fn, int line) if(p) { struct memhdr *mh; - if((mh=find_memhdr(p))) + if((mh=my_find_memhdr(p,0))) add_location(mh, location_number(fn,line)); } return p; @@ -1175,10 +1243,10 @@ void * debug_malloc_update_location(void *p,const char *fn, int line) void reset_debug_malloc(void) { INT32 h; - for(h=0;h<HSIZE;h++) + for(h=0;h<memhdr_hash_table_size;h++) { struct memhdr *m; - for(m=hash[h];m;m=m->next) + for(m=memhdr_hash_table[h];m;m=m->next) { struct memloc *l; for(l=m->locations;l;l=l->next) diff --git a/src/program.c b/src/program.c index e03168d6d037a2124008fb6baff8297c2fc76e1b..c03b2aaac7a6fb15d7ed15300b86f5afa027a72c 100644 --- a/src/program.c +++ b/src/program.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: program.c,v 1.122 1999/05/01 16:33:11 grubba Exp $"); +RCSID("$Id: program.c,v 1.123 1999/05/02 08:11:47 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -418,7 +418,7 @@ void optimize_program(struct program *p) #define FOO(NUMTYPE,TYPE,NAME) \ size=DO_ALIGN(size, ALIGNOF(TYPE)); \ MEMCPY(data+size,p->NAME,p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0])); \ - free((char *)p->NAME); \ + dmfree((char *)p->NAME); \ p->NAME=(TYPE *)(data+size); \ size+=p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]); #include "program_areas.h" @@ -682,17 +682,17 @@ void really_free_program(struct program *p) if(p->flags & PROGRAM_OPTIMIZED) { if(p->program) - free(p->program); + dmfree(p->program); #define FOO(NUMTYPE,TYPE,NAME) p->NAME=0; #include "program_areas.h" }else{ #define FOO(NUMTYPE,TYPE,NAME) \ - if(p->NAME) { free((char *)p->NAME); p->NAME=0; } + if(p->NAME) { dmfree((char *)p->NAME); p->NAME=0; } #include "program_areas.h" } FREE_PROT(p); - free((char *)p); + dmfree((char *)p); GC_FREE(); } @@ -746,7 +746,7 @@ static void toss_compilation_resources(void) if(malloc_size_program) { - free((char *)malloc_size_program); + dmfree((char *)malloc_size_program); malloc_size_program=0; } @@ -2801,7 +2801,7 @@ void pop_compiler_frame(void) free_string(f->current_return_type); compiler_frame=f->previous; - free((char *)f); + dmfree((char *)f); } diff --git a/src/signal_handler.c b/src/signal_handler.c index ccb59789944673ef254ee2fa84530662f33e26fc..427a2a371318613587341f65e642f3319c3dc991 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.128 1999/05/01 13:37:08 grubba Exp $"); +RCSID("$Id: signal_handler.c,v 1.129 1999/05/02 08:11:48 hubbe Exp $"); #ifdef HAVE_PASSWD_H # include <passwd.h> @@ -530,6 +530,7 @@ static void f_signal(int args) signal_evaluator_callback=add_to_callback(&evaluator_callbacks, check_signals, 0,0); + dmalloc_accept_leak(signal_evaluator_callback); } if(args == 1) @@ -2208,6 +2209,7 @@ void f_create_process(INT32 args) signal_evaluator_callback=add_to_callback(&evaluator_callbacks, check_signals, 0,0); + dmalloc_accept_leak(signal_evaluator_callback); } #endif @@ -2542,6 +2544,7 @@ void f_fork(INT32 args) signal_evaluator_callback=add_to_callback(&evaluator_callbacks, check_signals, 0,0); + dmalloc_accept_leak(signal_evaluator_callback); } #endif @@ -2860,6 +2863,7 @@ void init_signals(void) signal_evaluator_callback=add_to_callback(&evaluator_callbacks, check_signals, 0,0); + dmalloc_accept_leak(signal_evaluator_callback); } #ifdef USE_PID_MAPPING diff --git a/src/stralloc.c b/src/stralloc.c index ef6af50733bf08916d0e37558d07f20628e67b7a..d07f13d955890b9d4f320c89775a736d8183e139 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -23,7 +23,7 @@ #define HUGE HUGE_VAL #endif /*!HUGE*/ -RCSID("$Id: stralloc.c,v 1.58 1999/04/01 17:20:17 hubbe Exp $"); +RCSID("$Id: stralloc.c,v 1.59 1999/05/02 08:11:49 hubbe Exp $"); #define BEGIN_HASH_SIZE 997 #define MAX_AVG_LINK_LENGTH 3 @@ -638,7 +638,7 @@ void really_free_string(struct pike_string *s) } #endif unlink_pike_string(s); - free((char *)s); + debug_free((char *)s,__FILE__,__LINE__,1); } void debug_free_string(struct pike_string *s) diff --git a/src/threads.c b/src/threads.c index 48c21667649db81e61a3cc4de039a0e013f96a6e..71ebc4a70ec5f26dd00ad12613c2468cd61f7ac4 100644 --- a/src/threads.c +++ b/src/threads.c @@ -1,5 +1,5 @@ #include "global.h" -RCSID("$Id: threads.c,v 1.92 1999/04/02 23:23:47 hubbe Exp $"); +RCSID("$Id: threads.c,v 1.93 1999/05/02 08:11:50 hubbe Exp $"); int num_threads = 1; int threads_disabled = 0; @@ -560,6 +560,7 @@ void f_thread_create(INT32 args) { threads_evaluator_callback=add_to_callback(&evaluator_callbacks, check_threads, 0,0); + dmalloc_accept_leak(threads_evaluator_callback); } ref_push_object(arg->id); THREADS_FPRINTF(0, (stderr, "THREAD_CREATE -> t:%08x\n",