Repository navigation
_remote_debugging: async aware does not show tasks from a non-main thread #149230
Copy link
Copy link
Closed
Closed
Copy link
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
--async-aware does not show tasks in a non-main thread.
The docs do not restrict this to the main thread.
Anyway, it's using only the main thread now:
| unwinder->interpreter_addr + (uintptr_t)unwinder->debug_offsets.interpreter_state.threads_main, |
I think the fix as trivial as using the head:
cpython/Modules/_remote_debugging/module.c
Line 586 in b2f126c
| self->debug_offsets.interpreter_state.threads_head); |
h/t to Claude for helping me to find the root cause
What happened here is that I started to ponder why I'm not seeing lots of tasks when I should...
PS. Truth to be told, the docstring is a bit confusing, since (thread_id, awaited_by) is returned, not [frames, task_name, subtasks].
Reproduction
2026-05-01T16:16:53.769827000+0200 maurycy@gimel /Users/maurycy/src/github.com/maurycy/cpython (main c0e0640*?) % cat task_within_a_thread.py
import asyncio
import threading
import time
# Start a new async task in a new thread.
def sleeper():
asyncio.run(asyncio.sleep(99))
threading.Thread(target=sleeper, daemon=True).start()
time.sleep(99)
2026-05-01T16:16:55.131980000+0200 maurycy@gimel /Users/maurycy/src/github.com/maurycy/cpython (main c0e0640*?) % cat repro_min.py
import os
import subprocess
import sys
import time
import _remote_debugging
SCRIPT = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "task_within_a_thread.py"
)
p = subprocess.Popen([sys.executable, SCRIPT])
try:
time.sleep(0.5)
u = _remote_debugging.RemoteUnwinder(p.pid, all_threads=True, debug=True)
# Returns stack traces for all interpreters and threads in process.
sync = {t.thread_id for i in u.get_stack_trace() for t in i.threads}
# Get all tasks and their awaited_by relationships from the remote process.
aio = {a.thread_id for a in u.get_all_awaited_by()}
delta = sync - aio
print(
f"pid {p.pid} | sync {sorted(sync)} | asyncio iter {sorted(aio)} | misssed {sorted(delta)}"
)
finally:
p.terminate()
p.wait()
2026-05-01T16:16:56.529442000+0200 maurycy@gimel /Users/maurycy/src/github.com/maurycy/cpython (main c0e0640*?) % sudo ./python.exe repro_min.py
pid 12620 | sync [12624866, 12624867] | asyncio iter [0, 12624866] | misssed [12624867]
2026-05-01T16:17:01.050645000+0200 maurycy@gimel /Users/maurycy/src/github.com/maurycy/cpython (main c0e0640*?) % ./python.exe task_within_a_thread.py & PID=$!
[1] 12649
2026-05-01T16:17:06.852587000+0200 maurycy@gimel /Users/maurycy/src/github.com/maurycy/cpython (main c0e0640*?) % sudo ./python.exe -m profiling.sampling attach --async-aware --async-mode all -d 2 --collapsed -o async.txt $PID
Captured 2,000 samples in 2.00 seconds
Sample rate: 999.94 samples/sec
Error rate: 0.00
Collapsed stack output written to async.txt
2026-05-01T16:17:51.811493000+0200 maurycy@gimel /Users/maurycy/src/github.com/maurycy/cpython (main c0e0640*?) % cat async.txt
2026-05-01T16:17:54.585041000+0200 maurycy@gimel /Users/maurycy/src/github.com/maurycy/cpython (main c0e0640*?) % ls -l async.txt
-rw-r--r--@ 1 root staff 0 May 1 16:17 async.txt
2026-05-01T16:17:56.808086000+0200 maurycy@gimel /Users/maurycy/src/github.com/maurycy/cpython (main c0e0640*?) % CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Activity
maurycy commentedon May 1, 2026
cc @pablogsal As always, can do it
pythongh-149230: Test async tasks in non-main threads
gh-149230: `_remote_debugging`: Fix async-aware for tasks in non-main…