Blame SOURCES/procfs-Fix-removing-vanished-processes-in-pidstats.patch

12eebf
From cf4c740974834b7d5c9dc7b12a69c5269b0d7a2d Mon Sep 17 00:00:00 2001
12eebf
From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
12eebf
Date: Thu, 24 Jan 2019 21:55:16 +0100
12eebf
Subject: [PATCH] procfs: Fix removing vanished processes in
12eebf
 pidstats.reload_threads()
12eebf
MIME-Version: 1.0
12eebf
Content-Type: text/plain; charset=UTF-8
12eebf
Content-Transfer-Encoding: 8bit
12eebf
12eebf
If a process disappears while iterating the loop in
12eebf
pidstats.reload_threads(), we get a RuntimeError as shown below. This
12eebf
is because we cannot remove an entry from a dictionary while iterating the
12eebf
dictionary.
12eebf
12eebf
Reproducer:
12eebf
1. Add the following line to the beginning of pidstats.reload_threads():
12eebf
import pdb; pdb.set_trace()
12eebf
2. Start some process
12eebf
3. Start the python interpreter and proceed as follows:
12eebf
[~/git/python-linux-procfs]$ python3
12eebf
Python 3.6.8 (default, Jan  3 2019, 16:11:14)
12eebf
[GCC 8.2.1 20181215 (Red Hat 8.2.1-6)] on linux
12eebf
Type "help", "copyright", "credits" or "license" for more information.
12eebf
>>> import procfs
12eebf
>>> ps = procfs.pidstats()
12eebf
>>> ps.reload_threads()
12eebf
> /home/olysonek/git/python-linux-procfs/procfs/procfs.py(462)reload_threads()
12eebf
-> for pid in self.processes.keys():
12eebf
(Pdb) next
12eebf
> /home/olysonek/git/python-linux-procfs/procfs/procfs.py(463)reload_threads()
12eebf
-> try:
12eebf
12eebf
At this point, terminate the process started in step 2. Return to the
12eebf
python interpreter:
12eebf
12eebf
(Pdb) continue
12eebf
Traceback (most recent call last):
12eebf
  File "<stdin>", line 1, in <module>
12eebf
  File "/home/olysonek/git/python-linux-procfs/procfs/procfs.py", line 463, in reload_threads
12eebf
    try:
12eebf
RuntimeError: dictionary changed size during iteration
12eebf
12eebf
Signed-off-by: Ondřej Lysoněk <olysonek@redhat.com>
12eebf
Signed-off-by: John Kacur <jkacur@redhat.com>
12eebf
---
12eebf
 procfs/procfs.py | 5 ++++-
12eebf
 1 file changed, 4 insertions(+), 1 deletion(-)
12eebf
12eebf
diff --git a/procfs/procfs.py b/procfs/procfs.py
12eebf
index c6f65890d0e4..b0ce2514063d 100755
12eebf
--- a/procfs/procfs.py
12eebf
+++ b/procfs/procfs.py
12eebf
@@ -459,12 +459,15 @@ class pidstats:
12eebf
 			self.processes[pid] = process(pid, self.basedir)
12eebf
 
12eebf
 	def reload_threads(self):
12eebf
+		to_remove = []
12eebf
 		for pid in self.processes.keys():
12eebf
 			try:
12eebf
 				self.processes[pid].load_threads()
12eebf
 			except OSError:
12eebf
 				# process vanished, remove it
12eebf
-				del self.processes[pid]
12eebf
+				to_remove.append(pid)
12eebf
+		for pid in to_remove:
12eebf
+			del self.processes[pid]
12eebf
 
12eebf
 	def find_by_name(self, name):
12eebf
 		name = name[:15]
12eebf
-- 
12eebf
2.20.1
12eebf