Skip to content

Crash when accessing the asyncio module state in task deallocation #130221

@befeleme

Description

@befeleme

Crash report

What happened?

Cross posting from agronholm/anyio#870.

I noticed that with Python 3.14.0a5 (it doesn't happen in a4) anyio's tests for asyncio run successfully and only in the end the info about the core dumped is displayed.
You can see it by running the minimal reproducer (cut out from one of the tests) or in the interactive asyncio repl.
I suspect this is a regression in Python rather than an issue in anyio, but I couldn't figure out a reproducer without anyio code.

How can we reproduce the bug?

  • With Python 3.14.0a5 installed (in the snippet I use debug build of Python, but it will produce similar information when using the ordinary one)
    run python -m asyncio
>>> import asyncio
>>> from anyio import to_interpreter
>>> from functools import partial
>>> assert await to_interpreter.run_sync(partial(sorted, reverse=True), ["a", "b"]) == ["b", "a"]
>>> exit

result:

exiting asyncio REPL...
python3-debug: /builddir/build/BUILD/python3.14-3.14.0_a5-build/Python-3.14.0a5/Objects/typeobject.c:5262: PyType_GetModuleByDef: Assertion `mro != NULL' failed.

The underlying function to_thread.run_sync() seems to trigger the issue.
Running this as repr.py produces the same outcome. I ran it in gdb with Python debuginfo data, I attach the result.

import asyncio, io, anyio
 
async def repr():
    stream = io.BytesIO(b"data")
    assert await anyio.to_thread.run_sync(stream.read) == b"data"

asyncio.run(repr())
gdb stack trace
Starting program: /usr/bin/python3-debug repr.py

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.fedoraproject.org/>
Enable debuginfod for this session? (y or [n]) y
Debuginfod has been enabled.
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.
Downloading separate debug info for system-supplied DSO at 0x7ffff7fc5000
[Thread debugging using libthread_db enabled]                                                                          
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff61ff6c0 (LWP 47)]
[Thread 0x7ffff61ff6c0 (LWP 47) exited]
python3-debug: /builddir/build/BUILD/python3.14-3.14.0_a5-build/Python-3.14.0a5/Objects/typeobject.c:5262: PyType_GetModuleByDef: Assertion `mro != NULL' failed.

Thread 1 "python3-debug" received signal SIGABRT, Aborted.
Downloading source file /usr/src/debug/glibc-2.40.9000-37.fc43.x86_64/nptl/pthread_kill.c
__pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0)                   
    at pthread_kill.c:44
44            return INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0;
(gdb) bt
#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0)
    at pthread_kill.c:44
#1  0x00007ffff7480343 in __pthread_kill_internal (threadid=<optimized out>, signo=6) at pthread_kill.c:89
#2  0x00007ffff7426cbe in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007ffff740e6d6 in __GI_abort () at abort.c:73
#4  0x00007ffff740e639 in __assert_fail_base (fmt=<optimized out>, assertion=<optimized out>, file=<optimized out>, 
    line=5262, function=<optimized out>) at assert.c:118
#5  0x00007ffff77a883a in PyType_GetModuleByDef (type=0x555555852ca0, def=0x7ffff6911000 <_asynciomodule>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/typeobject.c:5262
#6  0x00007ffff68fb050 in get_asyncio_state_by_def (self=<_asyncio.Task() at remote 0x7ffff624ce60>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Modules/_asynciomodule.c:204
#7  0x00007ffff6903144 in TaskObj_dealloc (self=<_asyncio.Task() at remote 0x7ffff624ce60>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Modules/_asynciomodule.c:3068
#8  0x00007ffff7760214 in _Py_Dealloc (op=<_asyncio.Task() at remote 0x7ffff624ce60>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/object.c:3009
#9  0x00007ffff7735568 in Py_DECREF (
    filename=0x7ffff7c7b688 "/builddir/build/BUILD/python3.14-3.14.0_a5-build/Python-3.14.0a5/Include/refcount.h", 
    lineno=502, op=<_asyncio.Task() at remote 0x7ffff624ce60>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Include/refcount.h:393
#10 0x00007ffff77355bd in Py_XDECREF (op=<_asyncio.Task() at remote 0x7ffff624ce60>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Include/refcount.h:502
#11 0x00007ffff77373b9 in dictkeys_decref (interp=0x7ffff7e0c510 <_PyRuntime+105072>, dk=0x7ffff62353f0, 
    use_qsbr=false) at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:460
#12 0x00007ffff773db30 in dict_dealloc (
    self={'_default_interpreter_limiter': <unknown at remote 0x7ffff6274480>, '_available_workers': <collections.deque at remote 0x7ffff63c3250>, '_threadpool_idle_workers': <unknown at remote 0x7ffff63c3850>, '_threadpool_workers': <unknown at remote 0x7ffff6211a90>, '_root_task': <_asyncio.Task() at remote 0x7ffff624ce60>})
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:3266
#13 0x00007ffff7760214 in _Py_Dealloc (
    op={'_default_interpreter_limiter': <unknown at remote 0x7ffff6274480>, '_available_workers': <collections.deque at remote 0x7ffff63c3250>, '_threadpool_idle_workers': <unknown at remote 0x7ffff63c3850>, '_threadpool_workers': <unknown at remote 0x7ffff6211a90>, '_root_task': <_asyncio.Task() at remote 0x7ffff624ce60>})
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/object.c:3009
#14 0x00007ffff7735568 in Py_DECREF (
    filename=0x7ffff7c7b688 "/builddir/build/BUILD/python3.14-3.14.0_a5-build/Python-3.14.0a5/Include/refcount.h", 
    lineno=502, 
    op={'_default_interpreter_limiter': <unknown at remote 0x7ffff6274480>, '_available_workers': <collections.deque at remote 0x7ffff63c3250>, '_threadpool_idle_workers': <unknown at remote 0x7ffff63c3850>, '_threadpool_workers': <unknown at remote 0x7ffff6211a90>, '_root_task': <_asyncio.Task() at remote 0x7ffff624ce60>})
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Include/refcount.h:393
#15 0x00007ffff77355bd in Py_XDECREF (
    op={'_default_interpreter_limiter': <unknown at remote 0x7ffff6274480>, '_available_workers': <collections.deque at remote 0x7ffff63c3250>, '_threadpool_idle_workers': <unknown at remote 0x7ffff63c3850>, '_threadpool_workers': <unknown at remote 0x7ffff6211a90>, '_root_task': <_asyncio.Task() at remote 0x7ffff624ce60>})
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Include/refcount.h:502
#16 0x00007ffff7737441 in dictkeys_decref (interp=0x7ffff7e0c510 <_PyRuntime+105072>, dk=0x7ffff626e2c0, 
    use_qsbr=false) at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:468
#17 0x00007ffff773db30 in dict_dealloc (
    self={<unknown at remote 0x7ffff6270360>: {'_default_interpreter_limiter': <unknown at remote 0x7ffff6274480>, '_available_workers': <collections.deque at remote 0x7ffff63c3250>, '_threadpool_idle_workers': <unknown at remote 0x7ffff63c3850>, '_threadpool_workers': <unknown at remote 0x7ffff6211a90>, '_root_task': <_asyncio.Task() at remote 0x7ffff624ce60>}}) at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:3266
#18 0x00007ffff7760214 in _Py_Dealloc (
    op={<unknown at remote 0x7ffff6270360>: {'_default_interpreter_limiter': <unknown at remote 0x7ffff6274480>, '_avai--Type <RET> for more, q to quit, c to continue without paging--c
lable_workers': <collections.deque at remote 0x7ffff63c3250>, '_threadpool_idle_workers': <unknown at remote 0x7ffff63c3850>, '_threadpool_workers': <unknown at remote 0x7ffff6211a90>, '_root_task': <_asyncio.Task() at remote 0x7ffff624ce60>}}) at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/object.c:3009
#19 0x00007ffff7735568 in Py_DECREF (
    filename=0x7ffff7c94de0 "/builddir/build/BUILD/python3.14-3.14.0_a5-build/Python-3.14.0a5/Objects/dictobject.c", 
    lineno=7179, 
    op={<unknown at remote 0x7ffff6270360>: {'_default_interpreter_limiter': <unknown at remote 0x7ffff6274480>, '_available_workers': <collections.deque at remote 0x7ffff63c3250>, '_threadpool_idle_workers': <unknown at remote 0x7ffff63c3850>, '_threadpool_workers': <unknown at remote 0x7ffff6211a90>, '_root_task': <_asyncio.Task() at remote 0x7ffff624ce60>}}) at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Include/refcount.h:393
#20 0x00007ffff774551d in set_dict_inline_values (obj=<WeakKeyDictionary() at remote 0x7ffff6db2b00>, new_dict=0x0)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:7179
#21 0x00007ffff7745654 in set_or_clear_managed_dict (obj=<WeakKeyDictionary() at remote 0x7ffff6db2b00>, 
    new_dict=0x0, clear=true) at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:7313
#22 0x00007ffff77457d4 in PyObject_ClearManagedDict (obj=<WeakKeyDictionary() at remote 0x7ffff6db2b00>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:7351
#23 0x00007ffff77a2339 in subtype_dealloc (self=<WeakKeyDictionary() at remote 0x7ffff6db2b00>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/typeobject.c:2557
#24 0x00007ffff7760214 in _Py_Dealloc (op=<WeakKeyDictionary() at remote 0x7ffff6db2b00>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/object.c:3009
#25 0x00007ffff7735568 in Py_DECREF (
    filename=0x7ffff7c7b688 "/builddir/build/BUILD/python3.14-3.14.0_a5-build/Python-3.14.0a5/Include/refcount.h", 
    lineno=502, op=<WeakKeyDictionary() at remote 0x7ffff6db2b00>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Include/refcount.h:393
#26 0x00007ffff77355bd in Py_XDECREF (op=<WeakKeyDictionary() at remote 0x7ffff6db2b00>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Include/refcount.h:502
#27 0x00007ffff77373b9 in dictkeys_decref (interp=0x7ffff7e0c510 <_PyRuntime+105072>, dk=0x5555557888a0, 
    use_qsbr=false) at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:460
#28 0x00007ffff773cb85 in clear_lock_held (op={})
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:2865
#29 0x00007ffff773ccc4 in PyDict_Clear (op={})
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:2889
#30 0x00007ffff7740ea9 in dict_tp_clear (op={})
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Objects/dictobject.c:4608
#31 0x00007ffff792e0e5 in delete_garbage (tstate=0x7ffff7e432f0 <_PyRuntime+329808>, 
    gcstate=0x7ffff7e0e1f8 <_PyRuntime+112472>, collectable=0x7fffffffde80, old=0x7ffff7e0e228 <_PyRuntime+112520>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Python/gc.c:1130
#32 0x00007ffff792f8cd in gc_collect_region (tstate=0x7ffff7e432f0 <_PyRuntime+329808>, 
    from=0x7ffff7e0e228 <_PyRuntime+112520>, to=0x7ffff7e0e228 <_PyRuntime+112520>, stats=0x7fffffffdf40)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Python/gc.c:1745
#33 0x00007ffff792f62d in gc_collect_full (tstate=0x7ffff7e432f0 <_PyRuntime+329808>, stats=0x7fffffffdf40)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Python/gc.c:1665
#34 0x00007ffff79303fa in _PyGC_Collect (tstate=0x7ffff7e432f0 <_PyRuntime+329808>, generation=2, 
    reason=_Py_GC_REASON_SHUTDOWN) at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Python/gc.c:2026
#35 0x00007ffff7930501 in _PyGC_CollectNoFail (tstate=0x7ffff7e432f0 <_PyRuntime+329808>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Python/gc.c:2067
#36 0x00007ffff7a0e006 in finalize_modules (tstate=0x7ffff7e432f0 <_PyRuntime+329808>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Python/pylifecycle.c:1747
#37 0x00007ffff7a0e644 in _Py_Finalize (runtime=0x7ffff7df2aa0 <_PyRuntime>)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Python/pylifecycle.c:2078
#38 0x00007ffff7a0e706 in Py_FinalizeEx ()
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Python/pylifecycle.c:2204
#39 0x00007ffff7a58351 in Py_RunMain () at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Modules/main.c:768
#40 0x00007ffff7a58422 in pymain_main (args=0x7fffffffe0a0)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Modules/main.c:796
#41 0x00007ffff7a584ea in Py_BytesMain (argc=2, argv=0x7fffffffe218)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Modules/main.c:820
#42 0x00005555555544bd in main (argc=2, argv=0x7fffffffe218)
    at /usr/src/debug/python3.14-3.14.0~a5-1.fc43.x86_64/Programs/python.c:15

CPython versions tested on:

3.14

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.14bugs and security fixesextension-modulesC modules in the Modules dirtopic-asynciotype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions