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
This commit is contained in:
Willy Tarreau 2022-08-09 08:15:27 +02:00
parent 4bc37086b8
commit 55c950baa9
3 changed files with 10 additions and 4 deletions

View File

@ -245,6 +245,7 @@ struct mem_stats {
const char *file; const char *file;
int line; int line;
int type; int type;
const void *extra; // extra info specific to this call (e.g. pool ptr)
} __attribute__((aligned(sizeof(void*)))); } __attribute__((aligned(sizeof(void*))));
#undef calloc #undef calloc

View File

@ -259,6 +259,7 @@ static inline void *pool_get_from_cache(struct pool_head *pool, const void *call
.file = __FILE__, .line = __LINE__, \ .file = __FILE__, .line = __LINE__, \
.type = MEM_STATS_TYPE_P_FREE, \ .type = MEM_STATS_TYPE_P_FREE, \
}; \ }; \
_.extra = __pool; \
HA_WEAK("__start_mem_stats"); \ HA_WEAK("__start_mem_stats"); \
HA_WEAK("__stop_mem_stats"); \ HA_WEAK("__stop_mem_stats"); \
if (__ptr) { \ if (__ptr) { \
@ -275,6 +276,7 @@ static inline void *pool_get_from_cache(struct pool_head *pool, const void *call
.file = __FILE__, .line = __LINE__, \ .file = __FILE__, .line = __LINE__, \
.type = MEM_STATS_TYPE_P_ALLOC, \ .type = MEM_STATS_TYPE_P_ALLOC, \
}; \ }; \
_.extra = __pool; \
HA_WEAK("__start_mem_stats"); \ HA_WEAK("__start_mem_stats"); \
HA_WEAK("__stop_mem_stats"); \ HA_WEAK("__stop_mem_stats"); \
_HA_ATOMIC_INC(&_.calls); \ _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__, \ .file = __FILE__, .line = __LINE__, \
.type = MEM_STATS_TYPE_P_ALLOC, \ .type = MEM_STATS_TYPE_P_ALLOC, \
}; \ }; \
_.extra = __pool; \
HA_WEAK("__start_mem_stats"); \ HA_WEAK("__start_mem_stats"); \
HA_WEAK("__stop_mem_stats"); \ HA_WEAK("__stop_mem_stats"); \
_HA_ATOMIC_INC(&_.calls); \ _HA_ATOMIC_INC(&_.calls); \

View File

@ -1288,6 +1288,7 @@ static int debug_iohandler_memstats(struct appctx *appctx)
const char *type; const char *type;
const char *name; const char *name;
const char *p; const char *p;
const char *info = NULL;
if (!ptr->size && !ptr->calls && !ctx->show_all) if (!ptr->size && !ptr->calls && !ctx->show_all)
continue; 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_MALLOC: type = "MALLOC"; break;
case MEM_STATS_TYPE_REALLOC: type = "REALLOC"; break; case MEM_STATS_TYPE_REALLOC: type = "REALLOC"; break;
case MEM_STATS_TYPE_STRDUP: type = "STRDUP"; break; case MEM_STATS_TYPE_STRDUP: type = "STRDUP"; break;
case MEM_STATS_TYPE_P_ALLOC: type = "P_ALLOC"; 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"; 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; default: type = "UNSET"; break;
} }
@ -1318,10 +1319,11 @@ static int debug_iohandler_memstats(struct appctx *appctx)
chunk_printf(&trash, "%s:%d", name, ptr->line); chunk_printf(&trash, "%s:%d", name, ptr->line);
while (trash.data < 25) while (trash.data < 25)
trash.area[trash.data++] = ' '; 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, type,
(unsigned long)ptr->size, (unsigned long)ptr->calls, (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) { if (applet_putchk(appctx, &trash) == -1) {
ctx->start = ptr; ctx->start = ptr;