Skip to content

asyncio.subprocess blocked event loop unexpectedly on MacOS #158287

Description

@starstreammm

Bug report

Bug description:

After upgrading to 3.14.7 & macOS 27, this bug has happened.

When pausing the subprocess created by asyncio.create_subprocess_exec, it will blocked the whole event loop on MacOS.

Here is a minimal test code:

import asyncio
import psutil

async def main():
    proc = await asyncio.create_subprocess_exec(
        "sleep",
        "1000",
    )
    psutil.Process(proc.pid).suspend()

    print("child pid:", proc.pid, flush=True)

    count = 0
    while True:
        await asyncio.sleep(1)
        print(f"alive {count}", flush=True)
        count += 1

asyncio.run(main())

Expectly, it should print:

child pid: xxxxx
alive 0
alive 1
...

However, it just prints child pid: xxxxx, without any alive.

This issue isn't caused by psutil because the same result was got with kill -STOP xxxxx.

This runs well on Windows, but not on MacOS. This didn't happen on the previous version of 3.14.

CPython versions tested on:

3.14

Operating systems tested on:

macOS, Windows

Linked PRs

Activity

  1. picnixz commented on Sep 27, 2026

    @picnixz
    Member
  2. picnixz commented on Sep 27, 2026

    @picnixz
    Member

    @starstreammm Do you mean that on Python 3.14.6 it works well? or is it on 3.13 that it works well? (this is to confirm whether it's a release blocker or not)

  3. starstreammm commented on Sep 27, 2026

    @starstreammm
    Author

    @starstreammm Do you mean that on Python 3.14.6 it works well? or is it on 3.13 that it works well? (this is to confirm whether it's a release blocker or not)

    I updated my Python version yesterday. It had been quite a while since my last update, but I can confirm that I was already using 3.14 after the update. This issue didn't happen on that version. But I don't remember which version I used before exactly.

  4. picnixz commented on Sep 27, 2026

    @picnixz
    Member

    I'm going to let Kumar have a look at this issue and decide whether this is a release-blocker. At least, it's a regression AFAICT.

  5. deadlovelll commented on Sep 27, 2026

    @deadlovelll
    Contributor

    hey, i just took a quick look with my own tooling (on macos too)

    The trace:

    [EventLoopBlock] 'main' blocked the loop for 0.735s (threshold: 0.1s)
    Stack at the moment of blocking:
      File "/Users/timofeiivankov/cpython/repro.py", line 199, in <module>
        asyncio.run(main())
      File "/Users/timofeiivankov/cpython/Lib/asyncio/runners.py", line 205, in run
        return runner.run(main)
      File "/Users/timofeiivankov/cpython/Lib/asyncio/runners.py", line 128, in run
        return self._loop.run_until_complete(task)
      File "/Users/timofeiivankov/cpython/Lib/asyncio/base_events.py", line 712, in run_until_complete
        self.run_forever()
      File "/Users/timofeiivankov/cpython/Lib/asyncio/base_events.py", line 683, in run_forever
        self._run_once()
      File "/Users/timofeiivankov/cpython/Lib/asyncio/base_events.py", line 2090, in _run_once
        handle._run()
      File "/Users/timofeiivankov/cpython/Lib/asyncio/events.py", line 135, in _run
        return super()._run()
      File "/Users/timofeiivankov/cpython/Lib/asyncio/events.py", line 91, in _run
        self._context.run(self._callback, *self._args)
      File "/Users/timofeiivankov/cpython/Lib/asyncio/unix_events.py", line 1003, in _reap_and_notify
        pid, returncode = self._reap(loop, expected_pid)
      File "/Users/timofeiivankov/cpython/Lib/asyncio/unix_events.py", line 1008, in _reap
        pid, status = os.waitpid(expected_pid, 0)
    
    -> Culprit: _reap() at /Users/timofeiivankov/cpython/Lib/asyncio/unix_events.py:1008
    

    So _reap is probably the cause, or the code near it. If no one objects, I can work on the PR

  6. picnixz commented on Sep 27, 2026

    @picnixz
    Member

    Can you bisect the faulty commit first? @deadlovelll

  7. deadlovelll commented on Sep 27, 2026

    @deadlovelll
    Contributor

    Can you bisect the faulty commit first? @deadlovelll

    Faulty commit - 2875d1d (#153810). Fix is needed for main, 3.15 and 3.14

  8. added
    3.14bugs and security fixes
    3.15bugs and security fixes
    3.16new features, bugs and security fixes
    on Sep 27, 2026
  9. kumaraditya303 commented on Oct 5, 2026

    @kumaraditya303
    Contributor

    This seems like a macos kernel bug to me, dotnet is also hitting this quirk in dotnet/runtime#133930

    I think the fix is to exclude CLD_STOPPED manually here to avoid blocking in waitpid.

  10. added 4 commits that reference this issue on Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.14bugs and security fixes3.15bugs and security fixes3.16new features, bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytopic-asynciotype-bugAn unexpected behavior, bug, or error

    Projects

    • Status
      Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions