From 54c92f423fc81fc54c3df60dd6aba0a796b9ab75 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Mon, 8 Jun 2026 11:45:03 +0300 Subject: [PATCH] =?UTF-8?q?memory=5Fpool:=20=D1=83=D1=81=D0=B8=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D0=B0=D1=8F=20=D0=BA=D0=B0=D0=BD=D0=B0=D1=80=D0=B5?= =?UTF-8?q?=D0=B9=D0=BA=D0=B0=204B=20+=20=D1=85=D1=80=D0=B0=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20alloc=5Floc=20=D0=B4=D0=BB=D1=8F=20=D0=B4?= =?UTF-8?q?=D0=B8=D0=B0=D0=B3=D0=BD=D0=BE=D1=81=D1=82=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/memory_pool.c | 52 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/lib/memory_pool.c b/lib/memory_pool.c index 92b3da8d..8593b5bd 100644 --- a/lib/memory_pool.c +++ b/lib/memory_pool.c @@ -5,31 +5,55 @@ #include "memory_pool.h" #include "mem.h" -#define POOL_CANARY_OFF (pool->object_size) -#define POOL_TAG_OFF (pool->object_size + 1) -#define POOL_ALLOC_SIZE (pool->object_size + 2) -#define POOL_CANARY_VAL 0xAA - -static void pool_init_tags(struct memory_pool* pool, void* obj) +// Layout: [user_data: object_size] [canary: 4 bytes] [alloc_loc: pointer] [counter: 1 byte] +#define POOL_CANARY_OFF (pool->object_size) +#define POOL_LOC_OFF (pool->object_size + 4) +#define POOL_COUNTER_OFF (pool->object_size + 4 + sizeof(const char*)) +#define POOL_ALLOC_SIZE (pool->object_size + 4 + sizeof(const char*) + 1) +#define POOL_CANARY_VAL 0xDEADBEAF + +static void pool_init_tags(struct memory_pool* pool, void* obj, const char* location) { - uint8_t* canary = (uint8_t*)obj + POOL_CANARY_OFF; - uint8_t* counter = (uint8_t*)obj + POOL_TAG_OFF; + uint32_t* canary = (uint32_t*)((uint8_t*)obj + POOL_CANARY_OFF); + const char** loc = (const char**)((uint8_t*)obj + POOL_LOC_OFF); + uint8_t* counter = (uint8_t*)obj + POOL_COUNTER_OFF; *canary = POOL_CANARY_VAL; + *loc = location; *counter = 1; } +static void pool_dump_object(void* obj, size_t len, const char* prefix) +{ + unsigned char* p = (unsigned char*)obj; + char line[128]; + int pos; + size_t cnt = len < 32 ? len : 32; + pos = snprintf(line, sizeof(line), " %s [%zu]:", prefix, len); + for (size_t i = 0; i < cnt; i++) pos += snprintf(line + pos, sizeof(line) - pos, " %02x", p[i]); + DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "%s", line); +} + static void pool_check_and_clear_tags(struct memory_pool* pool, void* obj, const char* location) { - uint8_t* canary = (uint8_t*)obj + POOL_CANARY_OFF; - uint8_t* counter = (uint8_t*)obj + POOL_TAG_OFF; + uint32_t* canary = (uint32_t*)((uint8_t*)obj + POOL_CANARY_OFF); + const char** loc = (const char**)((uint8_t*)obj + POOL_LOC_OFF); + uint8_t* counter = (uint8_t*)obj + POOL_COUNTER_OFF; if (*canary != POOL_CANARY_VAL) { - DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "pool_free BUFFER OVERFLOW %p canary=0x%02x from %s! halting", obj, *canary, location); + DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "pool_free BUFFER OVERFLOW obj=%p sz=%zu alloc=%s free=%s canary=0x%08x expected=0x%08x", + obj, pool->object_size, *loc ? *loc : "(null)", location, *canary, POOL_CANARY_VAL); + pool_dump_object(obj, pool->object_size, "head"); + pool_dump_object((uint8_t*)obj + (pool->object_size > 32 ? pool->object_size - 32 : 0), + pool->object_size < 32 ? pool->object_size : 32, "tail"); + // dump raw canary area + DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, " canary_raw: %02x %02x %02x %02x loc=%p", + ((uint8_t*)canary)[0], ((uint8_t*)canary)[1], ((uint8_t*)canary)[2], ((uint8_t*)canary)[3], (void*)*loc); volatile int _halt = 1; while (_halt) {} } if (*counter == 0) { - DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "pool_free DOUBLE FREE %p from %s! halting", obj, location); + DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "pool_free DOUBLE FREE obj=%p alloc=%s free=%s! halting", + obj, *loc ? *loc : "(null)", location); volatile int _halt = 1; while (_halt) {} } @@ -70,7 +94,7 @@ void* memory_pool_alloc_impl(struct memory_pool* pool, const char* location) { g_total_free--; pool->reuse_count++; memset(obj, 0, pool->object_size); - pool_init_tags(pool, obj); + pool_init_tags(pool, obj, location); DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "pool_alloc reused: %s, remaining=%zu", location, pool->free_count); return obj; } @@ -78,7 +102,7 @@ void* memory_pool_alloc_impl(struct memory_pool* pool, const char* location) { pool->allocations++; DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "pool_alloc: %s, total_allocs=%zu", location, pool->allocations); void* obj = u_calloc_impl(1, POOL_ALLOC_SIZE, location); - if (obj) pool_init_tags(pool, obj); + if (obj) pool_init_tags(pool, obj, location); return obj; }