diff --git a/src/dmalloc.h b/src/dmalloc.h index 815a42a437097c5a3256185b8304c1f3cf76e0cb..f09fa2c49c4ba17b4050886756416aa8ce720359 100644 --- a/src/dmalloc.h +++ b/src/dmalloc.h @@ -3,14 +3,13 @@ extern int verbose_debug_malloc; extern int verbose_debug_exit; extern void *debug_malloc(size_t, const char *, int); -extern char *debug_xalloc(long, const char *, int); +extern char *debug_xalloc(long); 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 char *debug_strdup(const char *, const char *, int); void *debug_malloc_update_location(void *,const char *, int); #define malloc(x) debug_malloc((x), __FILE__, __LINE__) -#define xalloc(x) debug_xalloc((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__) @@ -18,10 +17,11 @@ void *debug_malloc_update_location(void *,const char *, int); #define DO_IF_DMALLOC(X) X #define debug_malloc_touch(X) debug_malloc_update_location((X),__FILE__,__LINE__) #define debug_malloc_pass(X) debug_malloc_update_location((X),__FILE__,__LINE__) +#define xalloc(X) ((char *)debug_malloc_touch(debug_xalloc(X))) #else +#define xalloc debug_xalloc #define dbm_main main #define DO_IF_DMALLOC(X) -extern char *xalloc(long); #define debug_malloc_update_location(X,Y,Z) (X) #define debug_malloc_touch(X) #define debug_malloc_pass(X) (X) diff --git a/src/error.h b/src/error.h index acc5186cfcd3b1e4396da813cb615ff0114a1eb9..2353b9697e7d9806838696b3f679e745ca2d7def 100644 --- a/src/error.h +++ b/src/error.h @@ -25,8 +25,11 @@ typedef void (*error_call)(void *); struct frame; #endif -#define THROW_ERROR 1 -#define THROW_EXIT 1000 +#define THROW_ERROR 10 +#define THROW_THREAD_EXIT 20 +#define THROW_THREAD_KILLED 30 +#define THROW_EXIT 40 +#define THROW_MAX_SEVERITY 100 typedef struct ONERROR { diff --git a/src/pike_memory.c b/src/pike_memory.c index 102443801fed005f86388d764c9fa673a5bd43d8..4954205893d6e07f85da8cf5b180693563d72abd 100644 --- a/src/pike_memory.c +++ b/src/pike_memory.c @@ -397,14 +397,31 @@ void memfill(char *to, } } +char *debug_xalloc(long size) +{ + char *ret; + if(!size) return 0; + + ret=(char *)malloc(size); + if(ret) return ret; + + error("Out of memory.\n"); + return 0; +} + #ifdef DEBUG_MALLOC -#undef xalloc +#ifdef _REENTRANT +#include "threads.h" + +static MUTEX_T debug_malloc_mutex; +#endif + + #undef malloc #undef free #undef realloc #undef calloc -#undef xalloc #undef strdup #undef main @@ -413,11 +430,13 @@ int verbose_debug_exit = 1; #define BSIZE 16382 #define HSIZE 65599 +#define LHSIZE 133153 struct memloc { struct memloc *next; const char *filename; + struct memhdr *mh; int line; int times; }; @@ -479,6 +498,7 @@ struct memloc_block static struct memloc_block *memloc_blocks=0; static struct memloc *free_memlocs=0; static struct memhdr no_leak_memlocs; +static struct memloc *mlhash[LHSIZE]; static struct memloc *alloc_memloc(void) { @@ -520,27 +540,67 @@ static struct memhdr *find_memhdr(void *p) return NULL; } +static unsigned long lhash(struct memhdr *m, + const char *fn, + int line) +{ + unsigned long l; + l=(long)m; + l*=53; + l+=(long)fn; + l*=4711; + l+=line; + l%=LHSIZE; + return l; +} + static void add_location(struct memhdr *mh, const char *fn, int line) { struct memloc *ml; + unsigned long l=lhash(mh,fn,line); + + if(mlhash[l] && + mlhash[l]->mh==mh && + mlhash[l]->filename==fn && + mlhash[l]->line==line) + return; + for(ml=mh->locations;ml;ml=ml->next) if(ml->filename==fn && ml->line==line) - return; + break; - ml=alloc_memloc(); - ml->line=line; - ml->filename=fn; - ml->next=mh->locations; - ml->times++; - mh->locations=ml; + if(!ml) + { + ml=alloc_memloc(); + ml->line=line; + ml->filename=fn; + ml->next=mh->locations; + ml->times++; + ml->mh=mh; + mh->locations=ml; + } + mlhash[l]=ml; } static int find_location(struct memhdr *mh, const char *fn, int line) { struct memloc *ml; + unsigned long l=lhash(mh,fn,line); + + if(mlhash[l] && + mlhash[l]->mh==mh && + mlhash[l]->filename==fn && + mlhash[l]->line==line) + return 1; + for(ml=mh->locations;ml;ml=ml->next) + { if(ml->filename==fn && ml->line==line) + { + mlhash[l]=ml; return 1; + } + } return 0; } @@ -548,8 +608,10 @@ static void make_memhdr(void *p, int s, const char *fn, int line) { struct memhdr *mh=alloc_memhdr(); struct memloc *ml=alloc_memloc(); + unsigned long l=lhash(mh,fn,line); unsigned long h=(long)p; h%=HSIZE; + mh->next=hash[h]; mh->data=p; mh->size=s; @@ -559,6 +621,7 @@ static void make_memhdr(void *p, int s, const char *fn, int line) ml->next=0; ml->times=1; hash[h]=mh; + mlhash[l]=ml; } static int remove_memhdr(void *p) @@ -573,6 +636,9 @@ static int remove_memhdr(void *p) struct memloc *ml; while((ml=mh->locations)) { + unsigned long l=lhash(mh,ml->filename, ml->line); + if(mlhash[l]==ml) mlhash[l]=0; + add_location(&no_leak_memlocs, ml->filename, ml->line); mh->locations=ml->next; ml->next=free_memlocs; @@ -590,42 +656,38 @@ static int remove_memhdr(void *p) void *debug_malloc(size_t s, const char *fn, int line) { - void *m=malloc(s); + void *m; + mt_lock(&debug_malloc_mutex); + m=malloc(s); if(m) make_memhdr(m, s, fn, line); if(verbose_debug_malloc) fprintf(stderr, "malloc(%d) => %p (%s:%d)\n", s, m, fn, line); + mt_unlock(&debug_malloc_mutex); return m; } -char *debug_xalloc(long size, const char *fn, int line) -{ - char *ret; - if(!size) return 0; - - ret=(char *)debug_malloc(size,fn, line); - if(ret) return ret; - - error("Out of memory.\n"); - return 0; -} void *debug_calloc(size_t a, size_t b, const char *fn, int line) { - void *m=calloc(a, b); + void *m; + mt_lock(&debug_malloc_mutex); + m=calloc(a, b); if(m) make_memhdr(m, a*b, fn, line); if(verbose_debug_malloc) fprintf(stderr, "calloc(%d,%d) => %p (%s:%d)\n", a, b, m, fn, line); + mt_unlock(&debug_malloc_mutex); return m; } void *debug_realloc(void *p, size_t s, const char *fn, int line) { void *m; + mt_lock(&debug_malloc_mutex); m=realloc(p, s); if(m) { if(p) remove_memhdr(p); @@ -633,31 +695,38 @@ void *debug_realloc(void *p, size_t s, const char *fn, int line) } if(verbose_debug_malloc) fprintf(stderr, "realloc(%p,%d) => %p (%s:%d)\n", p, s, m, fn,line); + mt_unlock(&debug_malloc_mutex); return m; } void debug_free(void *p, const char *fn, int line) { + mt_lock(&debug_malloc_mutex); remove_memhdr(p); free(p); if(verbose_debug_malloc) fprintf(stderr, "free(%p) (%s:%d)\n", p, fn,line); + mt_unlock(&debug_malloc_mutex); } char *debug_strdup(const char *s, const char *fn, int line) { - char *m=strdup(s); + char *m; + mt_lock(&debug_malloc_mutex); + m=strdup(s); if(m) make_memhdr(m, strlen(s)+1, fn, line); if(verbose_debug_malloc) fprintf(stderr, "strdup(\"%s\") => %p (%s:%d)\n", s, m, fn, line); + mt_unlock(&debug_malloc_mutex); return m; } static void cleanup_memhdrs() { unsigned long h; + mt_lock(&debug_malloc_mutex); if(verbose_debug_exit) { for(h=0;h<HSIZE;h++) @@ -678,6 +747,8 @@ static void cleanup_memhdrs() } } } + mt_unlock(&debug_malloc_mutex); + mt_destroy(&debug_malloc_mutex); } int main(int argc, char *argv[]) @@ -699,18 +770,4 @@ void * debug_malloc_update_location(void *p,const char *fn, int line) } -#else - -char *xalloc(long size) -{ - char *ret; - if(!size) return 0; - - ret=(char *)malloc(size); - if(ret) return ret; - - error("Out of memory.\n"); - return 0; -} - #endif diff --git a/src/pike_memory.h b/src/pike_memory.h index 5e97061800d1ae43d18ab367c90f2463725d4b39..3e124db0d74b181c873481daa8b252239b3efc0a 100644 --- a/src/pike_memory.h +++ b/src/pike_memory.h @@ -34,6 +34,7 @@ struct mem_searcher }; /* Prototypes begin here */ +extern char *debug_xalloc(long); void swap(char *a, char *b, INT32 size); void reverse(char *memory, INT32 nitems, INT32 size); void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order);