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 <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2013-11-03 00:00:00 -05:00 committed by Jaromir Capik
parent aa0e4e7fe2
commit 35dc6dcc49

View File

@ -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();