From b3c60d1de27cf24b9eec385a40b8652eebc22d38 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Wed, 21 Jun 2017 15:41:46 +0800 Subject: [PATCH] add MEMORY_CHECK macro to check double free --- skynet-src/malloc_hook.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/skynet-src/malloc_hook.c b/skynet-src/malloc_hook.c index 92834252..344b9fb6 100644 --- a/skynet-src/malloc_hook.c +++ b/skynet-src/malloc_hook.c @@ -9,6 +9,12 @@ #include "skynet.h" #include "atomic.h" +// turn on MEMORY_CHECK can do more memory check, such as double free +// #define MEMORY_CHECK + +#define MEMORY_ALLOCTAG 0x20140605 +#define MEMORY_FREETAG 0x0badf00d + static size_t _used_memory = 0; static size_t _memory_block = 0; @@ -17,8 +23,15 @@ struct mem_data { ssize_t allocated; }; +struct mem_cookie { + uint32_t handle; +#ifdef MEMORY_CHECK + uint32_t dogtag; +#endif +}; + #define SLOT_SIZE 0x10000 -#define PREFIX_SIZE sizeof(uint32_t) +#define PREFIX_SIZE sizeof(struct mem_cookie) static struct mem_data mem_stats[SLOT_SIZE]; @@ -76,9 +89,12 @@ inline static void* fill_prefix(char* ptr) { uint32_t handle = skynet_current_handle(); size_t size = je_malloc_usable_size(ptr); - uint32_t *p = (uint32_t *)(ptr + size - sizeof(uint32_t)); - memcpy(p, &handle, sizeof(handle)); - + struct mem_cookie *p = (struct mem_cookie *)(ptr + size - sizeof(struct mem_cookie)); + memcpy(&p->handle, &handle, sizeof(handle)); +#ifdef MEMORY_CHECK + uint32_t dogtag = MEMORY_ALLOCTAG; + memcpy(&p->dogtag, &dogtag, sizeof(dogtag)); +#endif update_xmalloc_stat_alloc(handle, size); return ptr; } @@ -86,9 +102,19 @@ fill_prefix(char* ptr) { inline static void* clean_prefix(char* ptr) { size_t size = je_malloc_usable_size(ptr); - uint32_t *p = (uint32_t *)(ptr + size - sizeof(uint32_t)); + struct mem_cookie *p = (struct mem_cookie *)(ptr + size - sizeof(struct mem_cookie)); uint32_t handle; - memcpy(&handle, p, sizeof(handle)); + memcpy(&handle, &p->handle, sizeof(handle)); +#ifdef MEMORY_CHECK + uint32_t dogtag; + memcpy(&dogtag, &p->dogtag, sizeof(dogtag)); + if (dogtag == MEMORY_FREETAG) { + fprintf(stderr, "xmalloc: double free in :%08x\n", handle); + } + assert(dogtag == MEMORY_ALLOCTAG); // memory out of bounds + dogtag = MEMORY_FREETAG; + memcpy(&p->dogtag, &dogtag, sizeof(dogtag)); +#endif update_xmalloc_stat_free(handle, size); return ptr; }