#include #undef NDEBUG #include #include #include #define DEBUG 1 #include "malloc.c" #include "debug_memory_c.h" #define N 4096 static struct alloc { unsigned long retadr1; unsigned long retadr2; int total; int count; int calls; int max; } allocs[N]; static int alloc_used; static int find_alloc_adr(unsigned long retadr1, unsigned long retadr2) { int i; for (i = 0; i < alloc_used; i++) if (allocs[i].retadr1 == retadr1 #ifdef GET_CALLERS_CALLER && allocs[i].retadr2 == retadr2 #endif ) return i; if (alloc_used >= N) abort(); i = alloc_used; allocs[i].retadr1 = retadr1; allocs[i].retadr2 = retadr2; allocs[i].total = allocs[i].count = 0; alloc_used++; return i; } struct header { unsigned long size; long entry; }; static void *mymalloc(size_t s, struct header **hdr) { struct header *h; void *mem = iti_malloc(s + sizeof(struct header)); if (!mem) return NULL; h = mem; h->size = s; h->entry = -1; if (hdr) *hdr = h; return (char *)mem + sizeof(struct header); } char *debug_malloc_adr(unsigned long retadr1, unsigned long retadr2, int size) { struct header *hdr; void *new = mymalloc(size, &hdr); struct alloc *info; int i; if (!new) return 0; i = find_alloc_adr(retadr1, retadr2); allocs[i].count++; allocs[i].calls++; allocs[i].total += size; if (allocs[i].total > allocs[i].max) allocs[i].max = allocs[i].total; hdr->entry = i; return new; } void free(void *p) { struct header *hdr = (struct header *)(p - sizeof(struct header)); int i; if (!p) return; i = hdr->entry; if (i >= 0) { allocs[i].count--; allocs[i].total -= hdr->size; } iti_free(hdr); } void *malloc(size_t s) { return debug_malloc_adr(RETADR1(), RETADR2(), s); } void *calloc(size_t n, size_t m) { int size = n * m; char *new = malloc(size); if (!new) return 0; memset(new, 0, size); return new; } void *realloc(void *old, size_t size) { struct header *hdr = (struct header *)((char *)old - sizeof(struct header)); char *new; int osize; if (!old) return malloc(size); if (!size) { free(old); return NULL; } new = malloc(size); osize = hdr->size; if (osize < size) size = osize; memcpy(new, old, size); iti_free(hdr); return new; } static int cmp_allocs(const void *e1, const void *e2) { const struct alloc *a1 = e1, *a2 = e2; return a1->max - a2->max; } void debug_alloced(void) { int i; qsort(allocs, alloc_used, sizeof(*allocs), cmp_allocs); #ifdef GET_CALLERS_CALLER for (i = 0; i < alloc_used; i++) fprintf(stderr, "*0x%08lx <- *0x%08lx: %d allocations for %d bytes (max %d, %d calls)\n", allocs[i].retadr1, allocs[i].retadr2, allocs[i].count, allocs[i].total, allocs[i].max, allocs[i].calls); #else for (i = 0; i < alloc_used; i++) fprintf(stderr, "*0x%08lx: %d allocations for %d bytes (max %d, %d calls)\n", allocs[i].retadr1, allocs[i].count, allocs[i].total, allocs[i].max, allocs[i].calls); #endif fflush(stderr); }