DEBUG: pools: pass the caller pointer to the check functions and macros

In preparation for more detailed pool error reports, let's pass the
caller pointers to the check functions. This will be useful to produce
messages indicating where the issue happened.
This commit is contained in:
Willy Tarreau 2023-09-11 11:14:43 +02:00
parent baf2070421
commit e92e96b00f
2 changed files with 7 additions and 6 deletions

View File

@ -70,7 +70,7 @@
*(typeof(pool)*)(((char *)__i) + __p->size) = __builtin_return_address(0); \
} while (0)
# define POOL_DEBUG_CHECK_MARK(pool, item) \
# define POOL_DEBUG_CHECK_MARK(pool, item, caller) \
do { \
typeof(pool) __p = (pool); \
typeof(item) __i = (item); \
@ -132,7 +132,7 @@ void pool_evict_from_local_cache(struct pool_head *pool, int full);
void pool_evict_from_local_caches(void);
void pool_put_to_cache(struct pool_head *pool, void *ptr, const void *caller);
void pool_fill_pattern(struct pool_cache_head *pch, struct pool_cache_item *item, uint size);
void pool_check_pattern(struct pool_cache_head *pch, struct pool_cache_item *item, uint size);
void pool_check_pattern(struct pool_cache_head *pch, struct pool_cache_item *item, uint size, const void *caller);
void pool_refill_local_from_shared(struct pool_head *pool, struct pool_cache_head *pch);
void pool_put_to_shared_cache(struct pool_head *pool, struct pool_item *item);
@ -252,7 +252,7 @@ static inline void *pool_get_from_cache(struct pool_head *pool, const void *call
item = LIST_PREV(&ph->list, typeof(item), by_pool);
if (pool_debugging & POOL_DBG_INTEGRITY)
pool_check_pattern(ph, item, pool->size);
pool_check_pattern(ph, item, pool->size, caller);
}
BUG_ON(&item->by_pool == &ph->list);

View File

@ -481,7 +481,7 @@ void pool_fill_pattern(struct pool_cache_head *pch, struct pool_cache_item *item
* must have been previously initialized using pool_fill_pattern(). If any
* corruption is detected, the function provokes an immediate crash.
*/
void pool_check_pattern(struct pool_cache_head *pch, struct pool_cache_item *item, uint size)
void pool_check_pattern(struct pool_cache_head *pch, struct pool_cache_item *item, uint size, const void *caller)
{
const ulong *ptr = (const ulong *)item;
uint ofs;
@ -511,6 +511,7 @@ static void pool_evict_last_items(struct pool_head *pool, struct pool_cache_head
{
struct pool_cache_item *item;
struct pool_item *pi, *head = NULL;
void *caller = __builtin_return_address(0);
uint released = 0;
uint cluster = 0;
uint to_free_max;
@ -525,7 +526,7 @@ static void pool_evict_last_items(struct pool_head *pool, struct pool_cache_head
item = LIST_PREV(&ph->list, typeof(item), by_pool);
BUG_ON(&item->by_pool == &ph->list);
if (unlikely(pool_debugging & POOL_DBG_INTEGRITY))
pool_check_pattern(ph, item, pool->size);
pool_check_pattern(ph, item, pool->size, caller);
LIST_DELETE(&item->by_pool);
LIST_DELETE(&item->by_lru);
@ -869,7 +870,7 @@ void __pool_free(struct pool_head *pool, void *ptr)
const void *caller = __builtin_return_address(0);
/* we'll get late corruption if we refill to the wrong pool or double-free */
POOL_DEBUG_CHECK_MARK(pool, ptr);
POOL_DEBUG_CHECK_MARK(pool, ptr, caller);
POOL_DEBUG_RESET_MARK(pool, ptr);
#ifdef USE_MEMORY_PROFILING