From 18b1a887b781e94391909fc7a8f7021309a8ebec Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Mon, 12 Sep 2016 16:16:16 -0500 Subject: [PATCH] top: finally circumvent that minor libnuma memory leak Still unhappy with a minor memory leak associated with libnuma, I experimented with omitting the dlclose that was issued at module's end. For some reason which will remain a mystery, the valgrind leak then went bye-bye. So this patch just omits one use of dlclose and relies on whatever kernel magic is at work to free the memory when each process ends. We kept, however, the original code (now commented-out) to serve as a future caution. There remains one potential (but unlikely) dlclose use near the original dlopen. But there will be no leak as that 'numa_node_of_cpu' will not yet have been called. This seems to be the culprit that triggers such leaks. None of this libnuma shit would likely have come close to hitting our fan had the numa developers provided us with 'new' and 'unref' functions like our newlib does. [ this commit parallels a patch in our newlib branch ] Signed-off-by: Jim Warner --- NEWS | 1 + top/top.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index c38c904a..0ff69ccb 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ procps-ng-NEXT * library: dont use vm_min_free on non Linux Debian #831396 * library: dont use SIGPWR on FreeBSD Debian #832148 * pmap: fix duplicate output line under '-x' option Redhat #1374061 + * top: eliminated minor libnuma memory leak procps-ng-3.3.12 ---------------- diff --git a/top/top.c b/top/top.c index d9730d86..3b09a5e0 100644 --- a/top/top.c +++ b/top/top.c @@ -552,7 +552,16 @@ static void bye_bye (const char *str) { #endif // end: OFF_HST_HASH #ifndef NUMA_DISABLE - if (Libnuma_handle) dlclose(Libnuma_handle); + /* note: we'll skip a dlcose() to avoid the following libnuma memory + * leak which is triggered after a call to numa_node_of_cpu(): + * ==1234== LEAK SUMMARY: + * ==1234== definitely lost: 512 bytes in 1 blocks + * ==1234== indirectly lost: 48 bytes in 2 blocks + * ==1234== ... + * [ thanks very much libnuma, for all the pain you've caused ] + */ +// if (Libnuma_handle) +// dlclose(Libnuma_handle); #endif if (str) { fputs(str, stderr); @@ -1717,7 +1726,7 @@ static FLD_t Fieldstab[] = { EU_UED, L_NONE - natural outgrowth of 'stat()' in readproc (euid) EU_CPU, L_stat - never filled by libproc, but requires times (pcpu) EU_CMD, L_stat - may yet require L_CMDLINE in calibrate_fields (cmd/cmdline) - L_EITHER - must L_status, else L_stat == 64-bit math (__udivdi3) on 32-bit ! + L_EITHER - favor L_stat (L_status == ++cost of gpref & hash scheme) .width .scale .align .sort .lflg ------ ------ -------- -------- -------- */ @@ -3318,6 +3327,8 @@ static void before (char *me) { if (Numa_max_node && Numa_node_of_cpu) Numa_node_tot = Numa_max_node() + 1; else { + // this dlclose is safe - we've yet to call numa_node_of_cpu + // ( there's one other dlclose which has now been disabled ) dlclose(Libnuma_handle); Libnuma_handle = NULL; }