From 55c950baa98b79759f3783c04415a628e0faa15a Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 9 Aug 2022 08:15:27 +0200 Subject: [PATCH] MINOR: debug: store and report the pool's name in struct mem_stats Let's add a generic "extra" pointer to the struct mem_stats to store context-specific information. When tracing pool_alloc/pool_free, we can now store a pointer to the pool, which allows to report the pool name on an extra column. This significantly improves tracing capabilities. Example: proxy.c:1598 CALLOC size: 28832 calls: 4 size/call: 7208 dynbuf.c:55 P_FREE size: 32768 calls: 2 size/call: 16384 buffer quic_tls.h:385 P_FREE size: 34008 calls: 1417 size/call: 24 quic_tls_iv quic_tls.h:389 P_FREE size: 34008 calls: 1417 size/call: 24 quic_tls_iv quic_tls.h:554 P_FREE size: 34008 calls: 1417 size/call: 24 quic_tls_iv quic_tls.h:558 P_FREE size: 34008 calls: 1417 size/call: 24 quic_tls_iv quic_tls.h:562 P_FREE size: 34008 calls: 1417 size/call: 24 quic_tls_iv quic_tls.h:401 P_ALLOC size: 34080 calls: 1420 size/call: 24 quic_tls_iv quic_tls.h:403 P_ALLOC size: 34080 calls: 1420 size/call: 24 quic_tls_iv xprt_quic.c:4060 MALLOC size: 45376 calls: 5672 size/call: 8 quic_sock.c:328 P_ALLOC size: 46440 calls: 215 size/call: 216 quic_dgram --- include/haproxy/bug.h | 1 + include/haproxy/pool.h | 3 +++ src/debug.c | 10 ++++++---- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h index fbf1d488e..1ca15a641 100644 --- a/include/haproxy/bug.h +++ b/include/haproxy/bug.h @@ -245,6 +245,7 @@ struct mem_stats { const char *file; int line; int type; + const void *extra; // extra info specific to this call (e.g. pool ptr) } __attribute__((aligned(sizeof(void*)))); #undef calloc diff --git a/include/haproxy/pool.h b/include/haproxy/pool.h index a818cc42b..579b53cb8 100644 --- a/include/haproxy/pool.h +++ b/include/haproxy/pool.h @@ -259,6 +259,7 @@ static inline void *pool_get_from_cache(struct pool_head *pool, const void *call .file = __FILE__, .line = __LINE__, \ .type = MEM_STATS_TYPE_P_FREE, \ }; \ + _.extra = __pool; \ HA_WEAK("__start_mem_stats"); \ HA_WEAK("__stop_mem_stats"); \ if (__ptr) { \ @@ -275,6 +276,7 @@ static inline void *pool_get_from_cache(struct pool_head *pool, const void *call .file = __FILE__, .line = __LINE__, \ .type = MEM_STATS_TYPE_P_ALLOC, \ }; \ + _.extra = __pool; \ HA_WEAK("__start_mem_stats"); \ HA_WEAK("__stop_mem_stats"); \ _HA_ATOMIC_INC(&_.calls); \ @@ -289,6 +291,7 @@ static inline void *pool_get_from_cache(struct pool_head *pool, const void *call .file = __FILE__, .line = __LINE__, \ .type = MEM_STATS_TYPE_P_ALLOC, \ }; \ + _.extra = __pool; \ HA_WEAK("__start_mem_stats"); \ HA_WEAK("__stop_mem_stats"); \ _HA_ATOMIC_INC(&_.calls); \ diff --git a/src/debug.c b/src/debug.c index 639f9375b..074af8117 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1288,6 +1288,7 @@ static int debug_iohandler_memstats(struct appctx *appctx) const char *type; const char *name; const char *p; + const char *info = NULL; if (!ptr->size && !ptr->calls && !ctx->show_all) continue; @@ -1304,8 +1305,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; + case MEM_STATS_TYPE_P_ALLOC: type = "P_ALLOC"; if (ptr->extra) info = ((const struct pool_head *)ptr->extra)->name; break; + case MEM_STATS_TYPE_P_FREE: type = "P_FREE"; if (ptr->extra) info = ((const struct pool_head *)ptr->extra)->name; break; default: type = "UNSET"; break; } @@ -1318,10 +1319,11 @@ static int debug_iohandler_memstats(struct appctx *appctx) chunk_printf(&trash, "%s:%d", name, ptr->line); while (trash.data < 25) trash.area[trash.data++] = ' '; - chunk_appendf(&trash, "%7s size: %12lu calls: %9lu size/call: %6lu\n", + chunk_appendf(&trash, "%7s size: %12lu calls: %9lu size/call: %6lu %s\n", type, (unsigned long)ptr->size, (unsigned long)ptr->calls, - (unsigned long)(ptr->calls ? (ptr->size / ptr->calls) : 0)); + (unsigned long)(ptr->calls ? (ptr->size / ptr->calls) : 0), + info ? info : ""); if (applet_putchk(appctx, &trash) == -1) { ctx->start = ptr;