mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-18 03:30:43 +00:00
MEDIUM: debug: improve DEBUG_MEM_STATS to also report pool alloc/free
Sometimes using "debug dev memstats" can be frustrating because all pool allocations are reported through pool-os.h and that's all. But in practice there's nothing wrong with also intercepting pool_alloc, pool_free and pool_zalloc and report their call counts and locations, so that's what this patch does. It only uses an alternate set of macroes for these 3 calls when DEBUG_MEM_STATS is defined. The outputs are reported as P_ALLOC (for both pool_malloc() and pool_zalloc()) and P_FREE (for pool_free()).
This commit is contained in:
parent
b8dec4a01a
commit
27061cd144
@ -233,6 +233,8 @@ enum {
|
||||
MEM_STATS_TYPE_MALLOC,
|
||||
MEM_STATS_TYPE_REALLOC,
|
||||
MEM_STATS_TYPE_STRDUP,
|
||||
MEM_STATS_TYPE_P_ALLOC,
|
||||
MEM_STATS_TYPE_P_FREE,
|
||||
};
|
||||
|
||||
struct mem_stats {
|
||||
|
@ -224,6 +224,8 @@ static inline void *pool_get_from_cache(struct pool_head *pool, const void *call
|
||||
|
||||
/****************** Common high-level code ******************/
|
||||
|
||||
#if !defined(DEBUG_MEM_STATS)
|
||||
|
||||
/*
|
||||
* Returns a pointer to type <type> taken from the pool <pool_type> or
|
||||
* dynamically allocated. Memory poisonning is performed if enabled.
|
||||
@ -247,6 +249,55 @@ static inline void *pool_get_from_cache(struct pool_head *pool, const void *call
|
||||
__pool_free(pool, __ptr); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#else /* DEBUG_MEM_STATS is set below */
|
||||
|
||||
#define pool_free(pool, ptr) ({ \
|
||||
struct pool_head *__pool = (pool); \
|
||||
typeof(ptr) __ptr = (ptr); \
|
||||
static struct mem_stats _ __attribute__((used,__section__("mem_stats"))) = { \
|
||||
.file = __FILE__, .line = __LINE__, \
|
||||
.type = MEM_STATS_TYPE_P_FREE, \
|
||||
}; \
|
||||
HA_WEAK("__start_mem_stats"); \
|
||||
HA_WEAK("__stop_mem_stats"); \
|
||||
if (__ptr) { \
|
||||
_HA_ATOMIC_INC(&_.calls); \
|
||||
_HA_ATOMIC_ADD(&_.size, __pool->size); \
|
||||
__pool_free(__pool, __ptr); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define pool_alloc(pool) ({ \
|
||||
struct pool_head *__pool = (pool); \
|
||||
size_t __x = __pool->size; \
|
||||
static struct mem_stats _ __attribute__((used,__section__("mem_stats"))) = { \
|
||||
.file = __FILE__, .line = __LINE__, \
|
||||
.type = MEM_STATS_TYPE_P_ALLOC, \
|
||||
}; \
|
||||
HA_WEAK("__start_mem_stats"); \
|
||||
HA_WEAK("__stop_mem_stats"); \
|
||||
_HA_ATOMIC_INC(&_.calls); \
|
||||
_HA_ATOMIC_ADD(&_.size, __x); \
|
||||
__pool_alloc(__pool, 0); \
|
||||
})
|
||||
|
||||
#define pool_zalloc(pool) ({ \
|
||||
struct pool_head *__pool = (pool); \
|
||||
size_t __x = __pool->size; \
|
||||
static struct mem_stats _ __attribute__((used,__section__("mem_stats"))) = { \
|
||||
.file = __FILE__, .line = __LINE__, \
|
||||
.type = MEM_STATS_TYPE_P_ALLOC, \
|
||||
}; \
|
||||
HA_WEAK("__start_mem_stats"); \
|
||||
HA_WEAK("__stop_mem_stats"); \
|
||||
_HA_ATOMIC_INC(&_.calls); \
|
||||
_HA_ATOMIC_ADD(&_.size, __x); \
|
||||
__pool_alloc(__pool, POOL_F_MUST_ZERO); \
|
||||
})
|
||||
|
||||
#endif /* DEBUG_MEM_STATS */
|
||||
|
||||
#endif /* _HAPROXY_POOL_H */
|
||||
|
||||
/*
|
||||
|
@ -1269,6 +1269,8 @@ static int debug_iohandler_memstats(struct appctx *appctx)
|
||||
case MEM_STATS_TYPE_MALLOC: type = "MALLOC"; break;
|
||||
case MEM_STATS_TYPE_REALLOC: type = "REALLOC"; break;
|
||||
case MEM_STATS_TYPE_STRDUP: type = "STRDUP"; break;
|
||||
case MEM_STATS_TYPE_P_ALLOC: type = "P_ALLOC"; break;
|
||||
case MEM_STATS_TYPE_P_FREE: type = "P_FREE"; break;
|
||||
default: type = "UNSET"; break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user