weird characters in top(1) output

John Baldwin jhb at freebsd.org
Tue Feb 1 14:53:14 UTC 2011


On Tuesday, February 01, 2011 8:11:54 am Alexander Best wrote:
> On Tue Feb  1 11, Sergey Kandaurov wrote:
> > On 1 February 2011 15:24, Alexander Best <arundel at freebsd.org> wrote:
> > > hi there,
> > >
> > > i was doing the following:
> > >
> > > top inf > ~/output
> > >
> > > when i noticed that this was missing the overall statistics line. so i went
> > > ahead and did:
> > >
> > > top -d2 inf > ~/output
> > >
> > > funny thing is that for the second output some weird characters seem to get
> > > spammed into the overall statistics line:
> > >
> > > last pid: 14320;  load averages:  0.42,  0.44,  0.37  up 1+14:02:02    13:21:05
> > > 249 processes: 1 running, 248 sleeping
> > > CPU: ^[[3;6H 7.8% user,  0.0% nice, 10.6% system,  0.6% interrupt, 81.0% idle
> > > Mem: 1271M Active, 205M Inact, 402M Wired, 67M Cache, 212M Buf, 18M Free
> > > Swap: 18G Total, 782M Used, 17G Free, 4% Inuse
> > >
> > > this only seems to happen when i redirect the top(1) output to a file. if i do:
> > >
> > > top -d2 inf
> > >
> > > ...everything works fine. i verified the issue under zsh(1) and sh(1).
> > 
> > My quick check shows that this is a regression between 7.2 and 7.3.
> > Reverting r196382 fixes this bug for me.
> 
> thanks for the help. indeed reverting r196382 fixes the issue.

Hmm, you need more than 10 CPUs to understand the reason for that fix.
Without it all of the updated per-CPU states are off by one column so you
get weird screen effects.  The "garbage" characters are actually just a
terminal sequence to move the cursor.  top uses these things a _lot_ to
move the cursor around.

You can try this instead though, it figures out the appropriate number of
spaces rather than using Move_to() for these two routines:

Index: display.c
===================================================================
--- display.c	(revision 218032)
+++ display.c	(working copy)
@@ -447,12 +447,14 @@
     /* print tag and bump lastline */
     if (num_cpus == 1)
 	printf("\nCPU: ");
-    else
-	printf("\nCPU %d: ", cpu);
+    else {
+	value = printf("\nCPU %d: ", cpu);
+	while (value++ <= cpustates_column)
+		printf(" ");
+    }
     lastline++;
 
     /* now walk thru the names and print the line */
-    Move_to(cpustates_column, y_cpustates + cpu);
     while ((thisname = *names++) != NULL)
     {
 	if (*thisname != '\0')
@@ -532,7 +534,7 @@
     register char **names;
     register char *thisname;
     register int *lp;
-    int cpu;
+    int cpu, value;
 
 for (cpu = 0; cpu < num_cpus; cpu++) {
     names = cpustate_names;
@@ -540,11 +542,13 @@
     /* show tag and bump lastline */
     if (num_cpus == 1)
 	printf("\nCPU: ");
-    else
-	printf("\nCPU %d: ", cpu);
+    else {
+	value = printf("\nCPU %d: ", cpu);
+	while (value++ <= cpustates_column)
+		printf(" ");
+    }
     lastline++;
 
-    Move_to(cpustates_column, y_cpustates + cpu);
     while ((thisname = *names++) != NULL)
     {
 	if (*thisname != '\0')

-- 
John Baldwin


More information about the freebsd-hackers mailing list