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
diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h
index fbf1d48..1ca15a6 100644
--- a/include/haproxy/bug.h
+++ b/include/haproxy/bug.h
@@ -245,6 +245,7 @@
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 a818cc4..579b53c 100644
--- a/include/haproxy/pool.h
+++ b/include/haproxy/pool.h
@@ -259,6 +259,7 @@
.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 @@
.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 @@
.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 639f937..074af81 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -1288,6 +1288,7 @@
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 @@
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 @@
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;