I attempted to replicate the trigger without pdb (using sys.monitoring directly, frame trace setters, sys.settrace, Bdb directly) without success. pdb's specific call chain seems necessary to reliably trigger it.
python: Objects/frameobject.c:2400: PyFrameObject *PyFrame_GetBack(PyFrameObject *): Assertion `!_PyFrame_IsIncomplete(frame->f_frame)' failed.
Thread 23 "Thread-22 (thre" received signal SIGABRT, Aborted.
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=0) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:89
#2 __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:100
#3 0x00007ffff7c45e2e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4 0x00007ffff7c28888 in __GI_abort () at ./stdlib/abort.c:77
#5 0x00007ffff7c287f0 in __assert_fail_base (fmt=<optimized out>, assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>) at ./assert/assert.c:118
#6 0x00007ffff7c3c19f in __assert_fail (assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>) at ./assert/assert.c:127
#7 0x0000555555b50d29 in PyFrame_GetBack (frame=frame@entry=0x7bffcc160410) at Objects/frameobject.c:2400
#8 0x0000555555b58c76 in frame_back_get_impl (self=0x7bffcc160410) at Objects/frameobject.c:1119
#9 frame_back_get (self=<optimized out>, _unused_context=<optimized out>) at Objects/clinic/frameobject.c.h:212
#10 0x0000555555c2cfb4 in _PyObject_GenericGetAttrWithDict (obj=0x7bffcc160410, name=0x7bffb60c0610, dict=0x0, suppress=0) at Objects/object.c:1924
#11 0x0000555555c2cab3 in _PyObject_GetAttrStackRef (v=0x7bffcc160410, name=0x7bffb60c0610) at Objects/object.c:1367
#12 0x0000555555edc322 in _PyEval_EvalFrameDefault (tstate=<optimized out>, frame=<optimized out>, throwflag=<optimized out>) at Python/generated_cases.c.h:8041
#13 0x0000555555ea8d04 in _PyEval_EvalFrame (tstate=0x7bffb4249010, frame=0x7e8ff709e328, throwflag=0) at ./Include/internal/pycore_ceval.h:118
#14 _PyEval_Vector (tstate=0x7bffb4249010, func=0x7bffb64cb1b0, locals=0x0, args=0x7bff9d4b9720, argcount=1, kwnames=0x0) at Python/ceval.c:2179
#15 0x0000555555ac6030 in _PyObject_VectorcallTstate (tstate=tstate@entry=0x7bffb4249010, callable=callable@entry=0x7bffb64cb1b0, args=0x7bff9d4b9720, nargsf=nargsf@entry=1,
kwnames=kwnames@entry=0x0) at ./Include/internal/pycore_call.h:144
#16 0x0000555555acbf7f in _PyObject_VectorcallPrepend (tstate=<optimized out>, callable=<optimized out>, arg=<error reading variable: Cannot access memory at address 0x6>,
args=<optimized out>, nargsf=0, kwnames=<optimized out>) at Objects/call.c:855
#17 0x0000555555f6b113 in _PyObject_VectorcallTstate (tstate=0x7bffb4249010, callable=0x7bffc82200d0, args=0x7bff9a2ab6c0, nargsf=22, kwnames=0x0) at ./Include/internal/pycore_call.h:144
#18 context_run (self=0x7bffb757cc10, args=args@entry=0x7bff9a2a96b0, nargs=nargs@entry=1, kwnames=kwnames@entry=0x0) at Python/context.c:727
#19 0x0000555555af812d in method_vectorcall_FASTCALL_KEYWORDS (func=func@entry=0x7bffb60a8820, args=args@entry=0x7bff9a2a96a8, nargsf=nargsf@entry=9223372036854775810,
kwnames=kwnames@entry=0x0) at Objects/descrobject.c:421
#20 0x0000555555ac6030 in _PyObject_VectorcallTstate (tstate=0x7bffb4249010, callable=0x7bffb60a8820, args=0x7bff9a2a96a8, nargsf=9223372036854775810, kwnames=0x0)
at ./Include/internal/pycore_call.h:144
#21 0x0000555555ea9e3b in _Py_VectorCallInstrumentation_StackRefSteal (callable=..., arguments=arguments@entry=0x7e8ff709e2f8, total_args=total_args@entry=2, kwnames=kwnames@entry=...,
call_instrumentation=false, frame=frame@entry=0x7e8ff709e298, this_instr=0x7bffc81901fe, tstate=0x7bffb4249010) at Python/ceval.c:775
#22 0x0000555555ee754d in _PyEval_EvalFrameDefault (tstate=<optimized out>, frame=<optimized out>, throwflag=<optimized out>) at Python/generated_cases.c.h:1841
#23 0x0000555555ea8d04 in _PyEval_EvalFrame (tstate=0x7bffb4249010, frame=0x7e8ff709e220, throwflag=0) at ./Include/internal/pycore_ceval.h:118
#24 _PyEval_Vector (tstate=0x7bffb4249010, func=0x7bffb64cb290, locals=0x0, args=0x7bff9d4b8220, argcount=1, kwnames=0x0) at Python/ceval.c:2179
#25 0x0000555555ac6030 in _PyObject_VectorcallTstate (tstate=tstate@entry=0x7bffb4249010, callable=callable@entry=0x7bffb64cb290, args=0x7bff9d4b8220, nargsf=nargsf@entry=1,
kwnames=kwnames@entry=0x0) at ./Include/internal/pycore_call.h:144
#26 0x0000555555acbf7f in _PyObject_VectorcallPrepend (tstate=<optimized out>, callable=<optimized out>, arg=<error reading variable: Cannot access memory at address 0x6>,
args=<optimized out>, nargsf=0, kwnames=<optimized out>) at Objects/call.c:855
#27 0x0000555555ac8802 in _PyVectorcall_Call (tstate=<optimized out>, func=<optimized out>, callable=<optimized out>, tuple=0x55555695f428 <_PyRuntime+173928>, kwargs=<optimized out>)
at Objects/call.c:273
#28 0x00005555562c9019 in thread_run (boot_raw=boot_raw@entry=0x7bffb41f08d0) at ./Modules/_threadmodule.c:387
#29 0x000055555610e226 in pythread_wrapper (arg=0x7bffb4010b50) at Python/thread_pthread.h:234
#30 0x00005555558a034b in asan_thread_start(void*) ()
Python 3.15.0a7+ free-threading build (heads/main:4d0e8ee649c, Mar 29 2026, 23:20:29) [Clang 21.1.2 (2ubuntu6)]
Crash report
What happened?
It's possible to cause an abort on a free-threaded build even with
PYTHON_GIL=1by running the code below (only reproduces with free threading enabled builds).I attempted to replicate the trigger without pdb (using sys.monitoring directly, frame trace setters, sys.settrace, Bdb directly) without success. pdb's specific call chain seems necessary to reliably trigger it.
MRE:
Backtrace:
Found using fusil by @vstinner.
CPython versions tested on:
CPython main branch, 3.15
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.15.0a7+ free-threading build (heads/main:4d0e8ee649c, Mar 29 2026, 23:20:29) [Clang 21.1.2 (2ubuntu6)]