]> granicus.if.org Git - procps-ng/commitdiff
top: address some potential libnuma display corruption
authorJim Warner <james.warner@comcast.net>
Sun, 3 Nov 2013 05:00:00 +0000 (00:00 -0500)
committerJaromir Capik <jcapik@redhat.com>
Mon, 4 Nov 2013 15:00:42 +0000 (16:00 +0100)
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>
top/top.c

index aa2777b26f9a47eab17b76d5a5755843ea2f6d35..a48a5b9172fec3096d278d89aacc2b0de99e6c8d 100644 (file)
--- 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();