NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/53906: systat(1) vmstat & syscall get "alternate system clock has died" on terminal resize (SIGWINCH)



>Number:         53906
>Category:       bin
>Synopsis:       systat(1) vmstat & syscall get "alternate system clock has died" on terminal resize (SIGWINCH)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jan 25 06:35:01 +0000 2019
>Originator:     Paul Ripke
>Release:        NetBSD 8.0_STABLE
>Organization:
Paul Ripke
"Great minds discuss ideas, average minds discuss events, small minds
 discuss people."
-- Disputed: Often attributed to Eleanor Roosevelt. 1948.
>Environment:
System: NetBSD slave 8.0_STABLE NetBSD 8.0_STABLE (SLAVE) #2: Mon Nov 5 16:27:42 AEDT 2018 stix@slave:/home/netbsd/netbsd-8/obj.amd64/home/netbsd/netbsd-8/src/sys/arch/amd64/compile/SLAVE amd64
Architecture: x86_64
Machine: amd64
>Description:
	When running systat with vmstat or syscall view, a terminal resize generates the "alternate system clock has died" and reverts to the pigs display, spins using a full core, and fails to respond to keys.
>How-To-Repeat:
	Start "systat vm" in an xterm, and resize the xterm.
>Fix:
	The fix for pr/53636 may have been the trigger, but the code is still broken as-is. The below patch fixes it for me - I opted to leave the "alternate system clock has died" code in, although it likely should be killed off. Crucially, we can't, and should not, call resizeterm(3) in redraw(), since this results in us receiving an endless stream of KEY_RESIZE events.

diff --git a/usr.bin/systat/main.c b/usr.bin/systat/main.c
index 3325d5f147bc..df0ffeb45ae3 100644
--- a/usr.bin/systat/main.c
+++ b/usr.bin/systat/main.c
@@ -332,7 +332,6 @@ display(int signo)
 void
 redraw(void)
 {
-	resizeterm(LINES, COLS);
 	CMDLINE = LINES - 1;
 	labels();
 
diff --git a/usr.bin/systat/syscall.c b/usr.bin/systat/syscall.c
index c943af2b11ae..1d27524ab044 100644
--- a/usr.bin/systat/syscall.c
+++ b/usr.bin/systat/syscall.c
@@ -43,6 +43,7 @@ __RCSID("$NetBSD: syscall.c,v 1.9 2014/02/19 20:42:14 dsl Exp $");
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <util.h>
 
 #include "systat.h"
@@ -197,10 +198,15 @@ showsyscall(void)
 	cpuswap();
 	if (display_mode == TIME) {
 		etime = cur.cp_etime;
-		/* < 5 ticks - ignore this trash */
+		/* < 1 ticks - sleep for a tick */
+		/* this is often triggered by repeated SIGWINCH */
 		if ((etime * hertz) < 1.0) {
-			if (failcnt++ <= MAXFAIL)
+			if (failcnt++ <= MAXFAIL) {
+				struct timespec interval = { 0, 1000000000L / hertz };
+				while (nanosleep(&interval, &interval) != 0)
+					;
 				return;
+			}
 			clear();
 			mvprintw(2, 10, "The alternate system clock has died!");
 			mvprintw(3, 10, "Reverting to ``pigs'' display.");
diff --git a/usr.bin/systat/vmstat.c b/usr.bin/systat/vmstat.c
index 526ee07f1304..ed92a34903ec 100644
--- a/usr.bin/systat/vmstat.c
+++ b/usr.bin/systat/vmstat.c
@@ -52,6 +52,7 @@ __RCSID("$NetBSD: vmstat.c,v 1.84 2019/01/08 08:22:20 tih Exp $");
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <util.h>
 
 #include "systat.h"
@@ -499,10 +500,15 @@ showvmstat(void)
 	if (display_mode == TIME) {
 		drvswap();
 		etime = cur.cp_etime;
-		/* < 5 ticks - ignore this trash */
+		/* < 1 ticks - sleep for a tick */
+		/* this is often triggered by repeated SIGWINCH */
 		if ((etime * hertz) < 1.0) {
-			if (failcnt++ <= MAXFAIL)
+			if (failcnt++ <= MAXFAIL) {
+				struct timespec interval = { 0, 1000000000L / hertz };
+				while (nanosleep(&interval, &interval) != 0)
+					;
 				return;
+			}
 			clear();
 			mvprintw(2, 10, "The alternate system clock has died!");
 			mvprintw(3, 10, "Reverting to ``pigs'' display.");



Home | Main Index | Thread Index | Old Index