summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Li <daniel.li@deshaw.com>2022-09-29 11:44:52 -0400
committerGitHub <noreply@github.com>2022-09-29 17:44:52 +0200
commit052c1e2ddbd712c201786b7cc9983a4284d3a6c8 (patch)
tree5634bf2f7488b38e2a4f38adcac562636269c119
parent69b572ef62ff349495d7884e231ed9faec7775c6 (diff)
downloadpsutil-052c1e2ddbd712c201786b7cc9983a4284d3a6c8.tar.gz
Resolve race condition in Process.threads() (#2151)
* Resolve race condition in Process.threads() Process.threads() has a race condition triggered when a thread exits after the open_binary() call and before the read() call. When this happens, the read() call raises ProcessLookupError. Handle the race condition by catching ProcessLookupError from read() and treating the same as a FileNotFoundError from open_binary(). This is the same approach used in ppid_map(). Signed-off-by: Daniel Li <daniel.li@deshaw.com> * Also catch ProcessLookupError in open_files() Signed-off-by: Daniel Li <daniel.li@deshaw.com>
-rw-r--r--CREDITS3
-rw-r--r--HISTORY.rst2
-rw-r--r--psutil/_pslinux.py8
3 files changed, 9 insertions, 4 deletions
diff --git a/CREDITS b/CREDITS
index 93866be5..65b9f4a2 100644
--- a/CREDITS
+++ b/CREDITS
@@ -798,3 +798,6 @@ N: Bernhard Urban-Forster
C: Austria
W: https://github.com/lewurm
I: 2135
+
+N: Daniel Li
+I: 2150
diff --git a/HISTORY.rst b/HISTORY.rst
index 263bad06..c9ea7320 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -14,6 +14,8 @@ XXXX-XX-XX
undefined ``ethtool_cmd_speed`` symbol.
- 2142_, [POSIX]: `net_if_stats()`_ 's ``flags`` on Python 2 returned unicode
instead of str. (patch by Matthieu Darbois)
+- 2150_, [Linux] `Process.threads()`_ may raise ``NoSuchProcess``. Fix race
+ condition. (patch by Daniel Li)
5.9.2
=====
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index 206241f6..9dc9643a 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -2061,9 +2061,9 @@ class Process(object):
try:
with open_binary(fname) as f:
st = f.read().strip()
- except FileNotFoundError:
- # no such file or directory; it means thread
- # disappeared on us
+ except (FileNotFoundError, ProcessLookupError):
+ # no such file or directory or no such process;
+ # it means thread disappeared on us
hit_enoent = True
continue
# ignore the first two values ("pid (exe)")
@@ -2217,7 +2217,7 @@ class Process(object):
with open_binary(file) as f:
pos = int(f.readline().split()[1])
flags = int(f.readline().split()[1], 8)
- except FileNotFoundError:
+ except (FileNotFoundError, ProcessLookupError):
# fd gone in the meantime; process may
# still be alive
hit_enoent = True