From 4edc620286e592b1a0c6c5bfd159745a1ee6e736 Mon Sep 17 00:00:00 2001 From: Daniel Li Date: Wed, 28 Sep 2022 20:57:24 -0400 Subject: [PATCH 1/2] 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 --- CREDITS | 3 +++ HISTORY.rst | 2 ++ psutil/_pslinux.py | 6 +++--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CREDITS b/CREDITS index 93866be5f..65b9f4a28 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 263bad066..c9ea73200 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 206241f6b..cf878c01d 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -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)") From f8bf7f264266ce4168f278d90144599ecd7d395a Mon Sep 17 00:00:00 2001 From: Daniel Li Date: Thu, 29 Sep 2022 11:21:06 -0400 Subject: [PATCH 2/2] Also catch ProcessLookupError in open_files() Signed-off-by: Daniel Li --- psutil/_pslinux.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index cf878c01d..9dc9643ab 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -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