Skip to content

Commit

Permalink
Resolve race condition in Process.threads() (#2151)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

* Also catch ProcessLookupError in open_files()

Signed-off-by: Daniel Li <[email protected]>
  • Loading branch information
li-dan authored Sep 29, 2022
1 parent 69b572e commit 052c1e2
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CREDITS
Original file line number Diff line number Diff line change
Expand Up @@ -798,3 +798,6 @@ N: Bernhard Urban-Forster
C: Austria
W: https://github.com/lewurm
I: 2135

N: Daniel Li
I: 2150
2 changes: 2 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
=====
Expand Down
8 changes: 4 additions & 4 deletions psutil/_pslinux.py
Original file line number Diff line number Diff line change
Expand Up @@ -2061,9 +2061,9 @@ def threads(self):
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)")
Expand Down Expand Up @@ -2217,7 +2217,7 @@ def open_files(self):
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
Expand Down

0 comments on commit 052c1e2

Please sign in to comment.