diff --git a/HISTORY.rst b/HISTORY.rst index 0ae9a74e0..89207a63a 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -10,6 +10,8 @@ **Bug fixes** +- 2395_, [OpenBSD]: `pid_exists()`_ erroneously return True if the argument is + a thread ID (TID) instead of a PID (process ID). - 2254_, [Linux]: offline cpus raise NotImplementedError in cpu_freq() (patch by Shade Gladden) - 2272_: Add pickle support to psutil Exceptions. - 2359_, [Windows], [CRITICAL]: `pid_exists()`_ disagrees with `Process`_ on diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index da68f5efd..4e67a9d85 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -561,10 +561,9 @@ def pids(): return ret -if OPENBSD or NETBSD: +if NETBSD: def pid_exists(pid): - """Return True if pid exists.""" exists = _psposix.pid_exists(pid) if not exists: # We do this because _psposix.pid_exists() lies in case of @@ -573,7 +572,19 @@ def pid_exists(pid): else: return True -else: +elif OPENBSD: + + def pid_exists(pid): + exists = _psposix.pid_exists(pid) + if not exists: + return False + else: + # OpenBSD seems to be the only BSD platform where + # _psposix.pid_exists() returns True for thread IDs (tids), + # so we can't use it. + return pid in pids() + +else: # FreeBSD pid_exists = _psposix.pid_exists diff --git a/psutil/tests/test_process_all.py b/psutil/tests/test_process_all.py index 68b720a4b..700ffe078 100755 --- a/psutil/tests/test_process_all.py +++ b/psutil/tests/test_process_all.py @@ -514,8 +514,12 @@ def check(pid): if not WINDOWS: # see docstring self.assertIn(pid, psutil.pids()) else: - with self.assertRaises(psutil.NoSuchProcess): - psutil.Process(pid) + # On OpenBSD thread IDs can be instantiated, + # and oneshot() succeeds, but other APIs fail + # with EINVAL. + if not OPENBSD: + with self.assertRaises(psutil.NoSuchProcess): + psutil.Process(pid) if not WINDOWS: # see docstring self.assertNotIn(pid, psutil.pids()) except (psutil.Error, AssertionError) as err: @@ -531,7 +535,8 @@ def check(pid): # Process class and is querable like a PID (process # ID). Skip it. continue - check(pid) + with self.subTest(pid=pid): + check(pid) if __name__ == '__main__':