X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Falloc-srvx.c;h=11de0fd637256199f0e22cd7e5d16246d65f16a2;hb=HEAD;hp=91d9035d2ecd2a4aa7cc154786c18d3ab285527d;hpb=7c855bda1a9a9bd80ee53cb99f70dd50e6ee48c2;p=srvx.git diff --git a/src/alloc-srvx.c b/src/alloc-srvx.c index 91d9035..11de0fd 100644 --- a/src/alloc-srvx.c +++ b/src/alloc-srvx.c @@ -15,13 +15,14 @@ */ #include "common.h" +#include "log.h" #undef malloc #undef free -/* cookies for anybody who recognizes these bytes without help :) */ #define ALLOC_MAGIC 0x1acf #define FREE_MAGIC 0xfc1d +const char redzone[] = { '\x03', '\x47', '\x76', '\xc7' }; struct alloc_header { unsigned int file_id : 8; @@ -32,6 +33,7 @@ struct alloc_header { static char file_id_map[256][32]; static unsigned int file_ids_used; +unsigned long alloc_count, alloc_size; static int file_id_cmp(const void *a_, const void *b_) @@ -57,43 +59,53 @@ srvx_malloc(const char *file, unsigned int line, size_t size) { struct alloc_header *block; - block = malloc(sizeof(*block) + size); + block = malloc(sizeof(*block) + size + sizeof(redzone)); assert(block != NULL); + if (block->magic == ALLOC_MAGIC && block->file_id < file_ids_used) { + /* Only report the error, due to possible false positives. */ + log_module(MAIN_LOG, LOG_WARNING, "Detected possible reallocation: %p (called by %s:%u/%lu; allocated by %u:%u/%u).", + block, file, line, (unsigned long)size, + block->file_id, block->line, block->size); + } memset(block, 0, sizeof(*block) + size); + memcpy((char*)(block + 1) + size, redzone, sizeof(redzone)); block->file_id = get_file_id(file); block->line = line; block->size = size; block->magic = ALLOC_MAGIC; + alloc_count++; + alloc_size += size; return block + 1; } void * srvx_realloc(const char *file, unsigned int line, void *ptr, size_t size) { - struct alloc_header *block = NULL, *newblock; + struct alloc_header *block, *newblock; - if (ptr) { - block = (struct alloc_header *)ptr - 1; - assert(block->magic == ALLOC_MAGIC); - if (block->size >= size) - return block + 1; - } + if (!ptr) + return srvx_malloc(file, line, size); - newblock = malloc(sizeof(*newblock) + size); + verify(ptr); + block = (struct alloc_header *)ptr - 1; + + if (block->size >= size) + return block + 1; + + newblock = malloc(sizeof(*newblock) + size + sizeof(redzone)); assert(newblock != NULL); - memset(newblock, 0, sizeof(*newblock) + size); + memset(newblock, 0, sizeof(*newblock)); + memcpy(newblock + 1, block + 1, block->size); + memset((char*)(newblock + 1) + block->size, 0, size - block->size); + memcpy((char*)(newblock + 1) + size, redzone, sizeof(redzone)); newblock->file_id = get_file_id(file); newblock->line = line; newblock->size = size; newblock->magic = ALLOC_MAGIC; + alloc_count++; + alloc_size += size; - if (ptr) { - memcpy(newblock + 1, block + 1, block->size); - size = block->size + sizeof(*block); - memset(block, 0, size); - block->magic = FREE_MAGIC; - free(block); - } + srvx_free(file, line, block + 1); return newblock + 1; } @@ -111,18 +123,30 @@ srvx_strdup(const char *file, unsigned int line, const char *src) } void -srvx_free(const char *file, unsigned int line, void *ptr) +srvx_free(UNUSED_ARG(const char *file), UNUSED_ARG(unsigned int line), void *ptr) { struct alloc_header *block; size_t size; if (!ptr) return; + verify(ptr); block = (struct alloc_header *)ptr - 1; - assert(block->magic == ALLOC_MAGIC); - size = block->size + sizeof(*block); - memset(block, 0, size); + size = block->size; + memset(block + 1, 0xde, size); block->magic = FREE_MAGIC; free(block); - (void)file; (void)line; + alloc_count--; + alloc_size -= size; +} + +void +verify(const void *ptr) +{ + const struct alloc_header *header; + if (!ptr) + return; + header = (const struct alloc_header*)ptr - 1; + assert(header->magic == ALLOC_MAGIC); + assert(!memcmp((char*)(header + 1) + header->size, redzone, sizeof(redzone))); }