#include #include #ifdef malloc #undef malloc #endif #ifdef realloc #undef realloc #endif #ifdef free #undef free #endif char guard[8] = { 0x10, 0x18, 0x19, 0x82, 0x12, 0x16, 0x20, 0x01 }; typedef struct _mem_entry_tag { size_t size; const char *a_file; int a_line; const char *f_file; int f_line; } MemEntryType; typedef MemEntryType *MemEntry; MemEntry *mem_table = 0; int mem_table_size = 0; int mem_table_capacity = 0; void *_lb_malloc(size_t size, const char *file, int line) { int i = mem_table_size; char *ptr; if (++mem_table_size > mem_table_capacity) { mem_table_capacity = mem_table_size + 50; mem_table = (MemEntry *)realloc(mem_table, mem_table_capacity * sizeof(MemEntry)); } mem_table[i] = (MemEntry)malloc(sizeof(MemEntryType) + size + 2 * sizeof(guard)); ptr = (char *)(mem_table[i] + 1); memcpy(ptr, guard, sizeof(guard)); ptr += sizeof(guard); memcpy(ptr + size, guard, sizeof(guard)); mem_table[i]->size = size; mem_table[i]->a_file = file; mem_table[i]->a_line = line; mem_table[i]->f_file = 0; mem_table[i]->f_line = 0; return ptr; } void *_lb_realloc(void *ptr, size_t size, const char *file, int line) { if (ptr) { char *pre_guard = (char *)ptr - sizeof(guard); MemEntry mem = (MemEntry)pre_guard - 1; if (mem->f_file) { fprintf(stderr, "%s:%d: Trying to realloc free'd memory\n", file, line); fprintf(stderr, "%s:%d: Previously free'd here\n", mem->f_file, mem->f_line); fprintf(stderr, "%s:%d: Previously allocated here\n", mem->a_file, mem->a_line); abort(); } if (memcmp(guard, pre_guard, sizeof(guard))) { fprintf(stderr, "%s:%d: Underflow detected during realloc\n", file, line); fprintf(stderr, "%s:%d: Previously allocated here\n", mem->a_file, mem->a_line); abort(); } if (memcmp(guard, pre_guard + sizeof(guard) + mem->size, sizeof(guard))) { fprintf(stderr, "%s:%d: Overflow detected during realloc\n", file, line); fprintf(stderr, "%s:%d: Previously allocated here\n", mem->a_file, mem->a_line); abort(); } mem = (MemEntry)realloc(mem, sizeof(MemEntryType) + 2 * sizeof(guard) + size); mem->a_file = file; mem->a_line = line; pre_guard = (char *)(mem + 1); memcpy(pre_guard + sizeof(guard) + size, guard, sizeof(guard)); return (void *)(pre_guard + sizeof(guard)); } else { return _lb_malloc(size, file, line); } } void _lb_free(void *ptr, const char *file, int line) { if (ptr) { char *pre_guard = (char *)ptr - sizeof(guard); MemEntry mem = (MemEntry)pre_guard - 1; if (mem->f_file) { fprintf(stderr, "%s:%d: Trying to free free'd memory\n", file, line); fprintf(stderr, "%s:%d: Previously free'd here\n", mem->f_file, mem->f_line); fprintf(stderr, "%s:%d: Previously allocated here\n", mem->a_file, mem->a_line); abort(); } if (memcmp(guard, pre_guard, sizeof(guard))) { fprintf(stderr, "%s:%d: Underflow detected during free\n", file, line); fprintf(stderr, "%s:%d: Previously allocated here\n", mem->a_file, mem->a_line); abort(); } if (memcmp(guard, pre_guard + sizeof(guard) + mem->size, sizeof(guard))) { fprintf(stderr, "%s:%d: Overflow detected during free\n", file, line); fprintf(stderr, "%s:%d: Previously allocated here\n", mem->a_file, mem->a_line); abort(); } mem->f_file = file; mem->f_line = line; } else { fprintf(stderr, "%s:%d: Attempting to free a NULL pointer\n", file, line); abort(); } } void _lb_mem_stats() { int i; for (i = 0; i < mem_table_capacity; i++) { char *pre_guard = (char *)(mem_table[i] + 1); if (!mem_table[i]->f_file) { fprintf(stderr, "%s:%d: Undeleted memory block\n", __FILE__, __LINE__); fprintf(stderr, "%s:%d: Previously allocated here\n", mem_table[i]->a_file, mem_table[i]->a_line); } if (memcmp(guard, pre_guard, sizeof(guard))) { fprintf(stderr, "%s:%d: Underflow detected\n", __FILE__, __LINE__); fprintf(stderr, "%s:%d: Previously allocated here\n", mem_table[i]->a_file, mem_table[i]->a_line); abort(); } if (memcmp(guard, pre_guard + sizeof(guard) + mem_table[i]->size, sizeof(guard))) { fprintf(stderr, "%s:%d: Overflow detected\n", __FILE__, __LINE__); fprintf(stderr, "%s:%d: Previously allocated here\n", mem_table[i]->a_file, mem_table[i]->a_line); abort(); } } }