diff options
author | Daniel Li <daniel.li@deshaw.com> | 2022-09-29 11:44:52 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-29 17:44:52 +0200 |
commit | 052c1e2ddbd712c201786b7cc9983a4284d3a6c8 (patch) | |
tree | 5634bf2f7488b38e2a4f38adcac562636269c119 | |
parent | 69b572ef62ff349495d7884e231ed9faec7775c6 (diff) | |
download | psutil-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-- | CREDITS | 3 | ||||
-rw-r--r-- | HISTORY.rst | 2 | ||||
-rw-r--r-- | psutil/_pslinux.py | 8 |
3 files changed, 9 insertions, 4 deletions
@@ -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 |