From: Willy Tarreau Date: Tue, 9 Aug 2022 07:08:18 +0000 (+0200) Subject: MINOR: debug/memstats: permit to pass the size to free() X-Git-Tag: v2.7-dev4~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db3716b8db98c45fcf24fd4a10d326c9a3b3e9c1;p=thirdparty%2Fhaproxy.git MINOR: debug/memstats: permit to pass the size to free() Right now the free() call is not intercepted since all this is done using macros and that would break a lot of stuff. Instead a __free() macro was provided but never used. In addition it used to only report a zero size, which is not very convenient. With this patch comes a better solution. Instead it provides a new will_free() macro that can be prepended before a call to free(). It only keeps the counters up to date, and also supports being passed a size. The pool_free_area() command now uses it, which finally allows the stats to look correct: pool-os.h:38 MALLOC size: 5802127832 calls: 3868044 size/call: 1500 pool-os.h:47 FREE size: 5800041576 calls: 3867444 size/call: 1499 The few other places directly calling free() could now be instrumented to use this and to pass the correct sizeof() when known. --- diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h index f4cc71b4ba..d65c1567c3 100644 --- a/include/haproxy/bug.h +++ b/include/haproxy/bug.h @@ -265,11 +265,14 @@ struct mem_stats { }) /* note: we can't redefine free() because we have a few variables and struct - * members called like this. + * members called like this. This one may be used before a call to free(), + * and when known, the size should be indicated, otherwise pass zero. The + * pointer is used to know whether the call should be accounted for (null is + * ignored). */ -#undef __free -#define __free(x) ({ \ - void *__x = (x); \ +#undef will_free +#define will_free(x, y) ({ \ + void *__x = (x); size_t __y = (y); \ static struct mem_stats _ __attribute__((used,__section__("mem_stats"),__aligned__(sizeof(void*)))) = { \ .file = __FILE__, .line = __LINE__, \ .type = MEM_STATS_TYPE_FREE, \ @@ -277,9 +280,10 @@ struct mem_stats { }; \ HA_WEAK("__start_mem_stats"); \ HA_WEAK("__stop_mem_stats"); \ - if (__x) \ + if (__x) { \ _HA_ATOMIC_INC(&_.calls); \ - free(__x); \ + _HA_ATOMIC_ADD(&_.size, __y); \ + } \ }) #undef ha_free @@ -345,6 +349,10 @@ struct mem_stats { _HA_ATOMIC_ADD(&_.size, __y); \ strdup(__x); \ }) +#else // DEBUG_MEM_STATS + +#define will_free(x, y) do { } while (0) + #endif /* DEBUG_MEM_STATS*/ #endif /* _HAPROXY_BUG_H */ diff --git a/include/haproxy/pool-os.h b/include/haproxy/pool-os.h index ef3c9353cc..d6612e8fe0 100644 --- a/include/haproxy/pool-os.h +++ b/include/haproxy/pool-os.h @@ -44,6 +44,7 @@ static forceinline void *pool_alloc_area(size_t size) */ static forceinline void pool_free_area(void *area, size_t __maybe_unused size) { + will_free(area, size); free(area); }