top vs. array sorted_state's out of bounds indexing (and related issues)
Date: Mon, 19 Jun 2023 04:23:06 UTC
usr.bin/top/machine.c (from main) has: /* . . . The process states are ordered as follows (from least * to most important): WAIT, zombie, sleep, stop, start, run. The * array declaration below maps a process state index into a number * that reflects this ordering. */ static int sorted_state[] = { 0, /* not used */ 3, /* sleep */ 1, /* ABANDONED (WAIT) */ 6, /* run */ 5, /* start */ 2, /* zombie */ 4 /* stop */ }; Note the elements are 0..6, so 7 elements. It is accessed via code like: sorted_state[(unsigned char)(b)->ki_stat] But ->ki_stat has the values listed in sys/sys/proc.h : /* * These were process status values (p_stat), now they are only used in * legacy conversion code. */ #define SIDL 1 /* Process being created by fork. */ #define SRUN 2 /* Currently runnable. */ #define SSLEEP 3 /* Sleeping on an address. */ #define SSTOP 4 /* Process debugging or suspension. */ #define SZOMB 5 /* Awaiting collection by parent. */ #define SWAIT 6 /* Waiting for interrupt. */ #define SLOCK 7 /* Blocked on a lock. */ This leads to element indexes (including the "unused" 0) of 0..7 so spanning 8 elements. Thus there is a out of bounds error involved when ->ki_stat == SLOCK . (I later show the ki_stat assignments.) There is also the issue that: SIDL is misidentified as: sleep SRUN is misidentified as: ABANDONED (WAIT) SSLEEP is misidentified as: run SZOMB is misidentified as: start SWAIT is misidentified as: zombie SLOCK is out of bounds (as indicated above). So the sort order in top is not as documented. For reference, from sys/kern/kern_proc.c : if (p->p_state == PRS_NORMAL) { /* approximate. */ if (TD_ON_RUNQ(td) || TD_CAN_RUN(td) || TD_IS_RUNNING(td)) { kp->ki_stat = SRUN; } else if (P_SHOULDSTOP(p)) { kp->ki_stat = SSTOP; } else if (TD_IS_SLEEPING(td)) { kp->ki_stat = SSLEEP; } else if (TD_ON_LOCK(td)) { kp->ki_stat = SLOCK; } else { kp->ki_stat = SWAIT; } } else if (p->p_state == PRS_ZOMBIE) { kp->ki_stat = SZOMB; } else { kp->ki_stat = SIDL; } === Mark Millard marklmi at yahoo.com