diff --git a/src/pike_memory.c b/src/pike_memory.c index d7778d29fd933aeb7f14ef8cb8c815b9b8eaa6a5..47b757cc951f47da7649ad2c55d43ad62faf89d1 100644 --- a/src/pike_memory.c +++ b/src/pike_memory.c @@ -463,6 +463,7 @@ int verbose_debug_exit = 1; #define HSIZE 1109891 #define LHSIZE 1109891 #define FLSIZE 8803 +#define DEBUG_MALLOC_PAD 8 struct fileloc { @@ -499,6 +500,59 @@ static struct memhdr *hash[HSIZE]; static struct memhdr no_leak_memlocs; static int file_location_number=0; +#if DEBUG_MALLOC_PAD - 0 > 0 +char *do_pad(char *mem, size_t size) +{ + long q,e; + mem+=DEBUG_MALLOC_PAD; + q= (((long)mem) ^ 0x555555) + (size * 9248339); + +/* fprintf(stderr,"Padding %p(%d) %ld\n",mem, size, q); */ +#if 1 + for(e=0;e< DEBUG_MALLOC_PAD; e++) + { + char tmp=q|1; + q=(q<<13) ^ ~(q>>5); + mem[e-DEBUG_MALLOC_PAD] = tmp; + mem[size+e] = tmp; + } +#endif + return mem; +} + +void check_pad(struct memhdr *mh) +{ + long q,e; + char *mem=mh->data; + size_t size=mh->size; + q= (((long)mem) ^ 0x555555) + (size * 9248339); + +/* fprintf(stderr,"Checking %p(%d) %ld\n",mem, size, q); */ +#if 1 + for(e=0;e< DEBUG_MALLOC_PAD; e++) + { + char tmp=q|1; + q=(q<<13) ^ ~(q>>5); + if(mem[e-DEBUG_MALLOC_PAD] != tmp) + { + fprintf(stderr,"Pre-padding overwritten for block at %p (size %d) (e=%ld %d!=%d)!\n",mem, size, e, tmp, mem[e-DEBUG_MALLOC_PAD]); + dump_memhdr_locations(mh, 0); + abort(); + } + if(mem[size+e] != tmp) + { + fprintf(stderr,"Post-padding overwritten for block at %p (size %d) (e=%ld %d!=%d)!\n",mem, size, e, tmp, mem[e-DEBUG_MALLOC_PAD]); + dump_memhdr_locations(mh, 0); + abort(); + } + } +#endif +} +#else +#define do_pad(X,Y) (X) +#define check_pad(M) +#endif + static int location_number(const char *file, int line) { struct fileloc *f,**prev; @@ -599,6 +653,7 @@ static struct memhdr *find_memhdr(void *p) *prev=mh->next; mh->next=hash[h]; hash[h]=mh; + check_pad(mh); return mh; } } @@ -679,7 +734,7 @@ static void make_memhdr(void *p, int s, int locnum) mlhash[l]=ml; } -static int remove_memhdr(void *p) +static int remove_memhdr(void *p, int already_gone) { struct memhdr **prev,*mh; unsigned long h=(long)p; @@ -688,6 +743,8 @@ static int remove_memhdr(void *p) { if(mh->data==p) { + if(!already_gone) check_pad(mh); + *prev=mh->next; low_add_marks_to_memhdr(&no_leak_memlocs, mh); free_memhdr(mh); @@ -700,13 +757,16 @@ static int remove_memhdr(void *p) void *debug_malloc(size_t s, const char *fn, int line) { - void *m; + char *m; mt_lock(&debug_malloc_mutex); - m=malloc(s); + m=(char *)malloc(s + DEBUG_MALLOC_PAD*2); if(m) + { + m=do_pad(m, s); make_memhdr(m, s, location_number(fn,line)); + } if(verbose_debug_malloc) fprintf(stderr, "malloc(%d) => %p (%s:%d)\n", s, m, fn, line); @@ -718,28 +778,31 @@ void *debug_malloc(size_t s, const char *fn, int line) void *debug_calloc(size_t a, size_t b, const char *fn, int line) { - void *m; - int locnum; - mt_lock(&debug_malloc_mutex); - m=calloc(a, b); - - if(m) make_memhdr(m, a*b, location_number(fn,line)); + void *m=debug_malloc(a*b,fn,line); + if(m) + MEMSET(m, 0, a*b); 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; + char *m,*base; mt_lock(&debug_malloc_mutex); - m=realloc(p, s); + + base=find_memhdr(p) ? (void *)(((char *)p)-DEBUG_MALLOC_PAD): p; + m=realloc(base, s+DEBUG_MALLOC_PAD*2); + if(m) { - if(p) remove_memhdr(p); - make_memhdr(m, s, location_number(fn,line)); + m=do_pad(m, s); + if(m != base) + { + if(p) remove_memhdr(p,1); + make_memhdr(m, s, location_number(fn,line)); + } } if(verbose_debug_malloc) fprintf(stderr, "realloc(%p,%d) => %p (%s:%d)\n", p, s, m, fn,line); @@ -750,7 +813,7 @@ void *debug_realloc(void *p, size_t s, const char *fn, int line) void debug_free(void *p, const char *fn, int line) { mt_lock(&debug_malloc_mutex); - remove_memhdr(p); + if(remove_memhdr(p,0)) p=((char *)p) - DEBUG_MALLOC_PAD; free(p); if(verbose_debug_malloc) fprintf(stderr, "free(%p) (%s:%d)\n", p, fn,line); @@ -760,14 +823,14 @@ void debug_free(void *p, const char *fn, int line) char *debug_strdup(const char *s, const char *fn, int line) { char *m; - mt_lock(&debug_malloc_mutex); - m=strdup(s); - - if(m) make_memhdr(m, strlen(s)+1, location_number(fn,line)); + long length; + length=strlen(s); + m=(char *)debug_malloc(length+1,fn,line); + MEMCPY(m,s,length+1); if(verbose_debug_malloc) fprintf(stderr, "strdup(\"%s\") => %p (%s:%d)\n", s, m, fn, line); - mt_unlock(&debug_malloc_mutex); + return m; } @@ -776,6 +839,7 @@ void dump_memhdr_locations(struct memhdr *from, struct memhdr *notfrom) { struct memloc *l; + if(!from) return; for(l=from->locations;l;l=l->next) { struct fileloc *f;