mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-01 17:10:42 +00:00
DEBUG/MEDIUM: memory: add optional control pool memory operations
When DEBUG_MEMORY_POOLS is used, we now use the link pointer at the end of the pool to store a pointer to the pool, and to control it during pool_free2() in order to serve four purposes : - at any instant we can know what pool an object was allocated from when examining memory, hence how we should possibly decode it ; - it serves to detect double free when they happen, as the pointer cannot be valid after the element is linked into the pool ; - it serves to detect if an element is released in the wrong pool ; - it serves as a canary, to detect if some buffers experienced an overflow before being release. All these elements will definitely help better troubleshoot strange situations, or at least confirm that certain conditions did not happen.
This commit is contained in:
parent
ac421118db
commit
de30a684ca
@ -124,6 +124,10 @@ static inline void *pool_get_first(struct pool_head *pool)
|
||||
if ((p = pool->free_list) != NULL) {
|
||||
pool->free_list = *POOL_LINK(pool, p);
|
||||
pool->used++;
|
||||
#ifdef DEBUG_MEMORY_POOLS
|
||||
/* keep track of where the element was allocated from */
|
||||
*POOL_LINK(pool, p) = (void *)pool;
|
||||
#endif
|
||||
}
|
||||
return p;
|
||||
}
|
||||
@ -154,8 +158,16 @@ static inline void *pool_alloc2(struct pool_head *pool)
|
||||
void *p;
|
||||
|
||||
p = pool_alloc_dirty(pool);
|
||||
if (p && mem_poison_byte >= 0)
|
||||
#ifdef DEBUG_MEMORY_POOLS
|
||||
if (p) {
|
||||
/* keep track of where the element was allocated from */
|
||||
*POOL_LINK(pool, p) = (void *)pool;
|
||||
}
|
||||
#endif
|
||||
if (p && mem_poison_byte >= 0) {
|
||||
memset(p, mem_poison_byte, pool->size);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -171,6 +183,11 @@ static inline void *pool_alloc2(struct pool_head *pool)
|
||||
static inline void pool_free2(struct pool_head *pool, void *ptr)
|
||||
{
|
||||
if (likely(ptr != NULL)) {
|
||||
#ifdef DEBUG_MEMORY_POOLS
|
||||
/* we'll get late corruption if we refill to the wrong pool or double-free */
|
||||
if (*POOL_LINK(pool, ptr) != (void *)pool)
|
||||
*(int *)0 = 0;
|
||||
#endif
|
||||
*POOL_LINK(pool, ptr) = (void *)pool->free_list;
|
||||
pool->free_list = (void *)ptr;
|
||||
pool->used--;
|
||||
|
@ -116,6 +116,10 @@ void *pool_refill_alloc(struct pool_head *pool, unsigned int avail)
|
||||
pool->free_list = ptr;
|
||||
}
|
||||
pool->used++;
|
||||
#ifdef DEBUG_MEMORY_POOLS
|
||||
/* keep track of where the element was allocated from */
|
||||
*POOL_LINK(pool, ptr) = (void *)pool;
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user