From 35dc6dcc49cc9cf8cff4300cb03a38dbe44c05db Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sun, 3 Nov 2013 00:00:00 -0500 Subject: [PATCH] top: address some potential libnuma display corruption There is a chance that the libnuma library may corrupt top's display with some stderr warning messages in the event something under /sys/devices/system/node/ cannot be accessed. And, while 2 overridable 'weak' functions are provided to alter such behavior, we can't use them since top dynamically links to the library via dlopen. This commit will redirect stderr to '/dev/null' during just the first screen display cycle. Thus we can avoid the corruption which would have remained visible until the underlining screen row's data had finally changed. Lastly, this patch should allow such a library warning to actually appear when one finally exits our program. [ i think the libnuma folks should consider changing ] [ the error/warning interfaces to accommodate dlopen ] [ rather than forcing something like the ugly kludge ] [ we have employed or libnuma dependency on everyone ] Reference(s): https://bugzilla.redhat.com/show_bug.cgi?id=998678 Signed-off-by: Jim Warner --- top/top.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/top/top.c b/top/top.c index aa2777b2..a48a5b91 100644 --- a/top/top.c +++ b/top/top.c @@ -220,6 +220,7 @@ static int Numa_node_tot; static int Numa_node_sel = -1; #ifndef NUMA_DISABLE static void *Libnuma_handle; +static int stderr_save = -1; #if defined(PRETEND_NUMA) || defined(PRETEND8CPUS) static int Numa_max_node(void) { return 3; } static int Numa_node_of_cpu(int num) { return (num % 4); } @@ -4043,6 +4044,17 @@ static void wins_stage_2 (void) { // fill in missing Fieldstab members and build each window's columnhdr zap_fieldstab(); +#ifndef NUMA_DISABLE + /* there's a chance that damn libnuma may spew to stderr so we gotta + make sure he does not corrupt poor ol' top's first output screen! + Yes, he provides some overridable 'weak' functions to change such + behavior but we can't exploit that since we don't follow a normal + ld route to symbol resolution (we use that dlopen() guy instead)! */ + stderr_save = dup(fileno(stderr)); + if (-1 < stderr_save && freopen("/dev/null", "w", stderr)) + ; // avoid -Wunused-result +#endif + // lastly, initialize a signal set used to throttle one troublesome signal sigemptyset(&Sigwinch_set); #ifdef SIGNALS_LESS @@ -5508,6 +5520,16 @@ static void frame_make (void) { the normal non-interactive output optimization... */ if (!Cap_can_goto) PSU_CLREOS(0); +#ifndef NUMA_DISABLE + /* we gotta reverse the stderr redirect which was employed in wins_stage_2 + and needed because the two libnuma 'weak' functions were useless to us! */ + if (-1 < stderr_save) { + dup2(stderr_save, fileno(stderr)); + close(stderr_save); + stderr_save = -1; + } +#endif + /* lastly, check auto-sized width needs for the next iteration */ if (AUTOX_MODE && Autox_found) widths_resize();