[Python-checkins] bpo-38982: Fix asyncio PidfdChildWatcher on waitpid() error (GH-17477)

Victor Stinner webhook-mailer at python.org
Fri Dec 6 10:32:47 EST 2019


https://github.com/python/cpython/commit/e76ee1a72b9e3f5da287663ea3daec4bb3f67612
commit: e76ee1a72b9e3f5da287663ea3daec4bb3f67612
branch: master
author: Victor Stinner <vstinner at python.org>
committer: GitHub <noreply at github.com>
date: 2019-12-06T16:32:41+01:00
summary:

bpo-38982: Fix asyncio PidfdChildWatcher on waitpid() error (GH-17477)

If waitpid() is called elsewhere, waitpid() call fails with
ChildProcessError: use return code 255 in this case, and log a
warning. It ensure that the pidfd file descriptor is closed if this
error occurs.

files:
A Misc/NEWS.d/next/Library/2019-12-05-18-21-26.bpo-38982.W3u-03.rst
M Lib/asyncio/unix_events.py

diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 97198ea2f4953..28fb491864517 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -930,9 +930,20 @@ def add_child_handler(self, pid, callback, *args):
     def _do_wait(self, pid):
         pidfd, callback, args = self._callbacks.pop(pid)
         self._loop._remove_reader(pidfd)
-        _, status = os.waitpid(pid, 0)
+        try:
+            _, status = os.waitpid(pid, 0)
+        except ChildProcessError:
+            # The child process is already reaped
+            # (may happen if waitpid() is called elsewhere).
+            returncode = 255
+            logger.warning(
+                "child process pid %d exit status already read: "
+                " will report returncode 255",
+                pid)
+        else:
+            returncode = _compute_returncode(status)
+
         os.close(pidfd)
-        returncode = _compute_returncode(status)
         callback(pid, returncode, *args)
 
     def remove_child_handler(self, pid):
diff --git a/Misc/NEWS.d/next/Library/2019-12-05-18-21-26.bpo-38982.W3u-03.rst b/Misc/NEWS.d/next/Library/2019-12-05-18-21-26.bpo-38982.W3u-03.rst
new file mode 100644
index 0000000000000..b591209ea06ef
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-12-05-18-21-26.bpo-38982.W3u-03.rst
@@ -0,0 +1,5 @@
+Fix asyncio ``PidfdChildWatcher``: handle ``waitpid()`` error. If
+``waitpid()`` is called elsewhere, ``waitpid()`` call fails with
+:exc:`ChildProcessError`: use return code 255 in this case, and log a
+warning. It ensures that the pidfd file descriptor is closed if this error
+occurs.



More information about the Python-checkins mailing list