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.
This commit is contained in:
parent
4a426e2082
commit
db3716b8db
@ -265,11 +265,14 @@ struct mem_stats {
|
|||||||
})
|
})
|
||||||
|
|
||||||
/* note: we can't redefine free() because we have a few variables and struct
|
/* 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
|
#undef will_free
|
||||||
#define __free(x) ({ \
|
#define will_free(x, y) ({ \
|
||||||
void *__x = (x); \
|
void *__x = (x); size_t __y = (y); \
|
||||||
static struct mem_stats _ __attribute__((used,__section__("mem_stats"),__aligned__(sizeof(void*)))) = { \
|
static struct mem_stats _ __attribute__((used,__section__("mem_stats"),__aligned__(sizeof(void*)))) = { \
|
||||||
.file = __FILE__, .line = __LINE__, \
|
.file = __FILE__, .line = __LINE__, \
|
||||||
.type = MEM_STATS_TYPE_FREE, \
|
.type = MEM_STATS_TYPE_FREE, \
|
||||||
@ -277,9 +280,10 @@ struct mem_stats {
|
|||||||
}; \
|
}; \
|
||||||
HA_WEAK("__start_mem_stats"); \
|
HA_WEAK("__start_mem_stats"); \
|
||||||
HA_WEAK("__stop_mem_stats"); \
|
HA_WEAK("__stop_mem_stats"); \
|
||||||
if (__x) \
|
if (__x) { \
|
||||||
_HA_ATOMIC_INC(&_.calls); \
|
_HA_ATOMIC_INC(&_.calls); \
|
||||||
free(__x); \
|
_HA_ATOMIC_ADD(&_.size, __y); \
|
||||||
|
} \
|
||||||
})
|
})
|
||||||
|
|
||||||
#undef ha_free
|
#undef ha_free
|
||||||
@ -345,6 +349,10 @@ struct mem_stats {
|
|||||||
_HA_ATOMIC_ADD(&_.size, __y); \
|
_HA_ATOMIC_ADD(&_.size, __y); \
|
||||||
strdup(__x); \
|
strdup(__x); \
|
||||||
})
|
})
|
||||||
|
#else // DEBUG_MEM_STATS
|
||||||
|
|
||||||
|
#define will_free(x, y) do { } while (0)
|
||||||
|
|
||||||
#endif /* DEBUG_MEM_STATS*/
|
#endif /* DEBUG_MEM_STATS*/
|
||||||
|
|
||||||
#endif /* _HAPROXY_BUG_H */
|
#endif /* _HAPROXY_BUG_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)
|
static forceinline void pool_free_area(void *area, size_t __maybe_unused size)
|
||||||
{
|
{
|
||||||
|
will_free(area, size);
|
||||||
free(area);
|
free(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user