Skip to content

Assertion failure or SystemError in _PyEval_EvalFrameDefault in a JIT build #137728

@devdanzin

Description

@devdanzin

Crash report

What happened?

It's possible to abort due to a failed assertion in _PyEval_EvalFrameDefault or raise a SystemError in a JIT build by running the code generated by the script below, which creates 4096 assignments inside the f1 function:

from pathlib import Path

header = """
def f1():
    for _ in range(5000):
         v = 0

"""

footer = """
f1()
"""


num_vars = 4096
per_line = 8

body_lines = []
for x in range(1, num_vars, per_line):
    vars_assign = [f"v{x}_{y} = " for y in range(per_line)]
    body_lines.append("".join(vars_assign) + str(x))

body = "    " + "\n    ".join(body_lines)

jit_crasher = Path("jit_crasher_01.py")
jit_crasher.write_text(header + body + footer)

Abort traceback:

python: Python/generated_cases.c.h:12283: _PyEval_EvalFrameDefault: Assertion `_PyErr_Occurred(tstate)' failed.

Program 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  0x00007ffff7c4579e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff7c288cd in __GI_abort () at ./stdlib/abort.c:73
#5  0x00007ffff7c28830 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  0x00007ffff7c3be1f in __assert_fail (assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>) at ./assert/assert.c:127
#7  0x00005555557dd43c in _PyEval_EvalFrameDefault (tstate=0x555555ccb240 <_PyRuntime+331136>, frame=0x7ffff7b7c018, throwflag=0) at Python/generated_cases.c.h:12283
#8  0x00005555557dd965 in _PyEval_EvalFrame (tstate=tstate@entry=0x555555ccb240 <_PyRuntime+331136>, frame=frame@entry=0x7ffff7fac020, throwflag=throwflag@entry=0)
    at ./Include/internal/pycore_ceval.h:119
#9  0x00005555557ddb36 in _PyEval_Vector (tstate=tstate@entry=0x555555ccb240 <_PyRuntime+331136>, func=func@entry=0x7ffff746a990, locals=locals@entry=0x7ffff74786b0, args=args@entry=0x0,
    argcount=argcount@entry=0, kwnames=kwnames@entry=0x0) at Python/ceval.c:1981
#10 0x00005555557ddc32 in PyEval_EvalCode (co=co@entry=0x7ffff7489be0, globals=globals@entry=0x7ffff74786b0, locals=locals@entry=0x7ffff74786b0) at Python/ceval.c:872
#11 0x00005555558c38dc in run_eval_code_obj (tstate=tstate@entry=0x555555ccb240 <_PyRuntime+331136>, co=co@entry=0x7ffff7489be0, globals=globals@entry=0x7ffff74786b0,
    locals=locals@entry=0x7ffff74786b0) at Python/pythonrun.c:1365
#12 0x00005555558c3a82 in run_mod (mod=mod@entry=0x55555601cdd8, filename=filename@entry=0x7ffff74b28c0, globals=globals@entry=0x7ffff74786b0, locals=locals@entry=0x7ffff74786b0,
    flags=flags@entry=0x7fffffffd788, arena=arena@entry=0x7ffff74e4be0, interactive_src=0x0, generate_new_source=0) at Python/pythonrun.c:1436
#13 0x00005555558c4302 in pyrun_file (fp=fp@entry=0x555555d412f0, filename=filename@entry=0x7ffff74b28c0, start=start@entry=257, globals=globals@entry=0x7ffff74786b0,
    locals=locals@entry=0x7ffff74786b0, closeit=closeit@entry=1, flags=0x7fffffffd788) at Python/pythonrun.c:1293
#14 0x00005555558c5b94 in _PyRun_SimpleFileObject (fp=fp@entry=0x555555d412f0, filename=filename@entry=0x7ffff74b28c0, closeit=closeit@entry=1, flags=flags@entry=0x7fffffffd788)
    at Python/pythonrun.c:521
#15 0x00005555558c5d9a in _PyRun_AnyFileObject (fp=fp@entry=0x555555d412f0, filename=filename@entry=0x7ffff74b28c0, closeit=closeit@entry=1, flags=flags@entry=0x7fffffffd788)
    at Python/pythonrun.c:81
#16 0x00005555558f01fd in pymain_run_file_obj (program_name=program_name@entry=0x7ffff74c70d0, filename=filename@entry=0x7ffff74b28c0, skip_source_first_line=0) at Modules/main.c:410
#17 0x00005555558f0325 in pymain_run_file (config=config@entry=0x555555c962e0 <_PyRuntime+114208>) at Modules/main.c:429
#18 0x00005555558f0e6f in pymain_run_python (exitcode=exitcode@entry=0x7fffffffd904) at Modules/main.c:691
#19 0x00005555558f1124 in Py_RunMain () at Modules/main.c:772
#20 0x00005555558f119b in pymain_main (args=args@entry=0x7fffffffd960) at Modules/main.c:802
#21 0x00005555558f1269 in Py_BytesMain (argc=<optimized out>, argv=<optimized out>) at Modules/main.c:826
#22 0x00005555555e4136 in main (argc=<optimized out>, argv=<optimized out>) at ./Programs/python.c:15

SystemError traceback:

Traceback (most recent call last):
  File "/home/danzin/crashers/jit/reducing/jit_crasher_01.py", line 518, in <module>
    f1()
    ~~^^
  File "/home/danzin/crashers/jit/reducing/jit_crasher_01.py", line 4, in f1
    v = 0
    ^
SystemError: error return without exception set

This one was hard to reduce by hand, but ShrinkRay did a good job, good enough to show that all the messy fuzzer code was unnecessary and creating a bunch of variables was enough.

Edited to add:

Output with PYTHON_LLTRACE=4:

Optimizing f1 (/home/danzin/crashers/jit/reducing/jit_crasher_01.py:2) at byte offset 34
   1 ADD_TO_TRACE: _START_EXECUTOR (0, target=17, operand0=0x6082647cd5b2, operand1=0x7fffb3c8ebc0)
   2 ADD_TO_TRACE: _MAKE_WARM (0, target=0, operand0=0, operand1=0)
17: JUMP_BACKWARD_JIT(7)
   3 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=17, operand0=0, operand1=0xb3c93ce8)
   4 ADD_TO_TRACE: _SET_IP (0, target=17, operand0=0x6082647cd5b2, operand1=0)
   5 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=17, operand0=0, operand1=0x7fffb3c8e9f8, error_target=0)
12: FOR_ITER_RANGE(5)
   6 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=12, operand0=0, operand1=0x75d35e06ff6e)
   7 ADD_TO_TRACE: _SET_IP (0, target=12, operand0=0x6082647cd5a8, operand1=0x2)
   8 ADD_TO_TRACE: _ITER_CHECK_RANGE (5, target=12, operand0=0, operand1=0x608238203a42)
   9 ADD_TO_TRACE: _GUARD_NOT_EXHAUSTED_RANGE (5, target=12, operand0=0, operand1=0x58)
  10 ADD_TO_TRACE: _ITER_NEXT_RANGE (5, target=12, operand0=0, operand1=0x60823832820d, error_target=0)
14: STORE_FAST(0)
  11 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=14, operand0=0, operand1=0x1)
  12 ADD_TO_TRACE: _SET_IP (0, target=14, operand0=0x6082647cd5ac, operand1=0x75d35d3221b0)
  13 ADD_TO_TRACE: _STORE_FAST (0, target=14, operand0=0, operand1=0)
15: LOAD_SMALL_INT(0)
  14 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=15, operand0=0, operand1=0x608238238aee)
  15 ADD_TO_TRACE: _SET_IP (0, target=15, operand0=0x6082647cd5ae, operand1=0x7fffb3c8ea60)
  16 ADD_TO_TRACE: _LOAD_SMALL_INT (0, target=15, operand0=0, operand1=0)
16: STORE_FAST(1)
  17 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=16, operand0=0, operand1=0x7fffb3c8e9e0)
  18 ADD_TO_TRACE: _SET_IP (0, target=16, operand0=0x6082647cd5b0, operand1=0x75d35d322200)
  19 ADD_TO_TRACE: _STORE_FAST (1, target=16, operand0=0, operand1=0x7fffb3c8ea60)
  20 ADD_TO_TRACE: _JUMP_TO_TOP (0, target=0, operand0=0, operand1=0x75d35d322200)
Created a proto-trace for f1 (/home/danzin/crashers/jit/reducing/jit_crasher_01.py:2) at byte offset 34 -- length 20
python: Python/generated_cases.c.h:12283: _PyEval_EvalFrameDefault: Assertion `_PyErr_Occurred(tstate)' failed.
Aborted (core dumped)

Found using lafleur.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

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

Python 3.15.0a0 (heads/main:3964f974894, Aug 13 2025, 15:09:55) [GCC 14.2.0]

Linked PRs

Metadata

Metadata

Labels

interpreter-core(Objects, Python, Grammar, and Parser dirs)topic-JITtype-crashA hard crash of the interpreter, possibly with a core dump

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions