top: fix out-of-band read when using -p with exactly 20 pids
When using top
with -p
and exactly 20 pids, there is an out-of-band read
ylecuyer@ylecuyer-U32U:~/Projects/procps$ ./top/top -b -n 1 -p 1,338,333,4,336,6,7,8,9,10,11,12,13,14,15,16,339,18,19,20
top - 00:24:51 up 1:34, 1 user, load average: 0,47, 0,75, 1,13
Tasks: 22 total, 0 running, 22 sleeping, 0 stopped, 0 zombie
%Cpu0 : 13,3/0,0 13[||||||||||||| ]
%Cpu1 : 18,8/6,2 25[||||||||||||||||||||||||| ]
GiB Mem : 54,3/3,5 [ ]
GiB Swap: 1,6/2,0 [ ]
PID USER PR NI VIRT RES %CPU %MEM TIME+ S COMMAND
1 root 20 0 156,2m 8,8m 0,0 0,2 0:03.79 S /sbin/init splash
4 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.00 I [kworker/0:0H]
6 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.00 I [mm_percpu_wq]
7 root 20 0 0,0m 0,0m 0,0 0,0 0:02.72 S [ksoftirqd/0]
8 root 20 0 0,0m 0,0m 0,0 0,0 0:19.12 I [rcu_sched]
9 root 20 0 0,0m 0,0m 0,0 0,0 0:00.00 I [rcu_bh]
10 root rt 0 0,0m 0,0m 0,0 0,0 0:00.22 S [migration/0]
11 root rt 0 0,0m 0,0m 0,0 0,0 0:00.04 S [watchdog/0]
12 root 20 0 0,0m 0,0m 0,0 0,0 0:00.00 S [cpuhp/0]
13 root 20 0 0,0m 0,0m 0,0 0,0 0:00.00 S [cpuhp/1]
14 root rt 0 0,0m 0,0m 0,0 0,0 0:00.04 S [watchdog/1]
15 root rt 0 0,0m 0,0m 0,0 0,0 0:00.24 S [migration/1]
16 root 20 0 0,0m 0,0m 0,0 0,0 0:00.98 S [ksoftirqd/1]
18 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.00 I [kworker/1:0H]
2 root 20 0 0,0m 0,0m 0,0 0,0 0:00.02 S [kthreadd]
2 root 20 0 0,0m 0,0m 0,0 0,0 0:00.02 S `- [kthreadd]
19 root 20 0 0,0m 0,0m 0,0 0,0 0:00.01 S `- [kdevtmpfs]
20 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.00 I `- [netns]
333 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.01 S `- [loop3]
336 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.01 S `- [loop4]
338 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.01 S `- [loop5]
339 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.02 S `- [loop6]
Here you can see there are 22 tasks
2 root 20 0 0,0m 0,0m 0,0 0,0 0:00.02 S [kthreadd]
2 root 20 0 0,0m 0,0m 0,0 0,0 0:00.02 S `- [kthreadd]
Those 2 tasks shouldn't be here
This happen because when we use the -p
option, we fill the Monpids
array with the pids. Unused slots are initialized to 0
.
The PROCTAB finder is the listed_nextpid
as we have the PROC_PID
flag set
In the case where we have exactly 20 pids, all slots of Monpids
are filled and
pid_t tgid = *(PT->pids)++;
if(likely(tgid)){
...
}
Never encounter the end of the array. I have added an extra slot to the array so it ends correclty.
With the fix the output is now correct
ylecuyer@ylecuyer-U32U:~/Projects/procps$ ./top/top -b -n 1 -p 1,338,333,4,336,6,7,8,9,10,11,12,13,14,15,16,339,18,19,20
top - 00:26:38 up 1:35, 1 user, load average: 0,26, 0,60, 1,03
Tasks: 20 total, 0 running, 20 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0,0/0,0 0[ ]
%Cpu1 : 0,0/6,2 6[|||||| ]
GiB Mem : 54,2/3,5 [ ]
GiB Swap: 1,6/2,0 [ ]
PID USER PR NI VIRT RES %CPU %MEM TIME+ S COMMAND
1 root 20 0 156,2m 8,8m 0,0 0,2 0:03.79 S /sbin/init splash
4 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.00 I [kworker/0:0H]
6 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.00 I [mm_percpu_wq]
7 root 20 0 0,0m 0,0m 0,0 0,0 0:02.73 S [ksoftirqd/0]
8 root 20 0 0,0m 0,0m 0,0 0,0 0:19.37 I [rcu_sched]
9 root 20 0 0,0m 0,0m 0,0 0,0 0:00.00 I [rcu_bh]
10 root rt 0 0,0m 0,0m 0,0 0,0 0:00.22 S [migration/0]
11 root rt 0 0,0m 0,0m 0,0 0,0 0:00.04 S [watchdog/0]
12 root 20 0 0,0m 0,0m 0,0 0,0 0:00.00 S [cpuhp/0]
13 root 20 0 0,0m 0,0m 0,0 0,0 0:00.00 S [cpuhp/1]
14 root rt 0 0,0m 0,0m 0,0 0,0 0:00.04 S [watchdog/1]
15 root rt 0 0,0m 0,0m 0,0 0,0 0:00.24 S [migration/1]
16 root 20 0 0,0m 0,0m 0,0 0,0 0:00.98 S [ksoftirqd/1]
18 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.00 I [kworker/1:0H]
19 root 20 0 0,0m 0,0m 0,0 0,0 0:00.01 S [kdevtmpfs]
20 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.00 I [netns]
333 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.01 S [loop3]
336 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.01 S [loop4]
338 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.01 S [loop5]
339 root 0 -20 0,0m 0,0m 0,0 0,0 0:00.02 S [loop6]