python / python/cpython

JIT: Assertion `next_instr->op.code == STORE_FAST` failed in `_PyEval_EvalFrameDefault`

Open
#143,820 0 comments 0 reactions 1 assignee View on GitHub

@Fidget-Spinner is already working on this.

Since Jan 14, 2026.

interpreter-core topic-JIT type-crash
Dominant language
Python
Stars
77.2k
Forks
35.9k
PR merge metrics
PR metrics pending

Description

Crash report

What happened?

It's possible to cause an abort in a patched JIT build by running the code below.

Necessary patch:

diff --git a/Include/internal/pycore_backoff.h b/Include/internal/pycore_backoff.h
index fadd11f04ec..3e779a141af 100644
--- a/Include/internal/pycore_backoff.h
+++ b/Include/internal/pycore_backoff.h
@@ -125,7 +125,7 @@ trigger_backoff_counter(void)
 // For example, 4095 does not work for the nqueens benchmark on pyperformance
 // as we always end up tracing the loop iteration's
 // exhaustion iteration. Which aborts our current tracer.
-#define JUMP_BACKWARD_INITIAL_VALUE 4000
+#define JUMP_BACKWARD_INITIAL_VALUE 63
 #define JUMP_BACKWARD_INITIAL_BACKOFF 6
 static inline _Py_BackoffCounter
 initial_jump_backoff_counter(_PyPolicy *policy)
@@ -139,7 +139,7 @@ initial_jump_backoff_counter(_PyPolicy *policy)
  * Must be larger than ADAPTIVE_COOLDOWN_VALUE,
  * otherwise when a side exit warms up we may construct
  * a new trace before the Tier 1 code has properly re-specialized. */
-#define SIDE_EXIT_INITIAL_VALUE 4000
+#define SIDE_EXIT_INITIAL_VALUE 63
 #define SIDE_EXIT_INITIAL_BACKOFF 6

 static inline _Py_BackoffCounter
MRE

import sys
import random

int_v1 = 981679
int_v2 = -3791744241805517
any_v3 = 939.217

def f1(): int_v1 ^ int_v1

for i_f1 in range(300):
    f1()

def f2():
    class Int(int):
        def __index__(self):...

    inf = float('inf')
    nzero = -0
    zero = 0.0
    dummy = 0
    print('', file=sys.stderr)

    def f_0_dc_6103(p): return p + 1
    def f_1_dc_6103(p): return f_0_dc_6103(p) + 1
    def f_2_dc_6103(p): return f_1_dc_6103(p) + 1
    def f_3_dc_6103(p): return f_2_dc_6103(p) + 1
    def f_4_dc_6103(p): return f_3_dc_6103(p) + 1
    def f_5_dc_6103(p): return f_4_dc_6103(p) + 1
    def f_6_dc_6103(p): return f_5_dc_6103(p) + 1
    def f_7_dc_6103(p): return f_6_dc_6103(p) + 1
    def f_8_dc_6103(p): return f_7_dc_6103(p) + 1
    def f_9_dc_6103(p): return f_8_dc_6103(p) + 1

    if inf == inf: dummy += 1
    s = ''
    try:
        for _ in range(10):
            s += ''
        s += 'y'
    except Exception: pass
    int_v1 ^ int_v1
    int_v1 ^ int_v1
    int_v1 ^ int_v1
    int_v2 - int_v1
    int_v2 - int_v1
    int_v2 - int_v1
    int_v2 - int_v1
    int_v2 - int_v1
    not any_v3
    not any_v3
    not any_v3

for i_f2 in range(300):
    f2()

Backtrace

python: Python/generated_cases.c.h:416: PyObject *_PyEval_EvalFrameDefault(PyThreadState *, _PyInterpreterFrame *, int): Assertion `next_instr->op.code == STORE_FAST' 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  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  0x0000555555ec01ec in _PyEval_EvalFrameDefault (tstate=<optimized out>, frame=<optimized out>, throwflag=<optimized out>) at Python/generated_cases.c.h:416
#8  0x0000555555e72e68 in _PyEval_EvalFrame (tstate=0x555556ed3030 <_PyRuntime+359408>, frame=0x7e8ff6de5220, throwflag=0) at ./Include/internal/pycore_ceval.h:118
#9  _PyEval_Vector (tstate=<optimized out>, func=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kwnames=0x0) at Python/ceval.c:2541
#10 0x0000555555e72885 in PyEval_EvalCode (co=<optimized out>, globals=<optimized out>, locals=0x7c7ff6e863c0) at Python/ceval.c:1005
#11 0x000055555649d01f in run_eval_code_obj (tstate=tstate@entry=0x555556ed3030 <_PyRuntime+359408>, co=co@entry=0x7d2ff6dffa10, globals=globals@entry=0x7c7ff6e863c0,
    locals=locals@entry=0x7c7ff6e863c0) at Python/pythonrun.c:1366
#12 0x000055555649c1ec in run_mod (mod=<optimized out>, filename=<optimized out>, globals=<optimized out>, locals=<optimized out>, flags=<optimized out>, arena=<optimized out>,
    interactive_src=<optimized out>, generate_new_source=<optimized out>) at Python/pythonrun.c:1469
#13 0x00005555564967ed in pyrun_file (fp=fp@entry=0x7d4ff6defa80, filename=filename@entry=0x7cdff6defc50, start=start@entry=257, globals=globals@entry=0x7c7ff6e863c0,
    locals=locals@entry=0x7c7ff6e863c0, closeit=closeit@entry=1, flags=0x7bfff5c1e910) at Python/pythonrun.c:1294
#14 0x000055555649434d in _PyRun_SimpleFileObject (fp=<optimized out>, filename=<optimized out>, closeit=<optimized out>, flags=<optimized out>) at Python/pythonrun.c:518
#15 0x00005555564936be in _PyRun_AnyFileObject (fp=fp@entry=0x7d4ff6defa80, filename=filename@entry=0x7cdff6defc50, closeit=closeit@entry=1, flags=flags@entry=0x7bfff5c1e910)
    at Python/pythonrun.c:81
#16 0x000055555650ff2b in pymain_run_file_obj (program_name=0x7caff6e230d0, filename=0x7cdff6defc50, skip_source_first_line=0) at Modules/main.c:410
#17 pymain_run_file (config=0x555556e9e0f8 <_PyRuntime+142520>) at Modules/main.c:429
#18 0x000055555650dff4 in pymain_run_python (exitcode=0x7bfff5c1e500) at Modules/main.c:691
#19 Py_RunMain () at Modules/main.c:772
#20 0x000055555650eef7 in pymain_main (args=<optimized out>) at Modules/main.c:802
#21 0x000055555650f068 in Py_BytesMain (argc=<optimized out>, argv=0x7fffffffdb78) at Modules/main.c:826
#22 0x00007ffff7c2a575 in __libc_start_call_main (main=main@entry=0x55555591ec40 <main>, argc=argc@entry=2, argv=argv@entry=0x7fffffffdb78) at ../sysdeps/nptl/libc_start_call_main.h:58
#23 0x00007ffff7c2a628 in __libc_start_main_impl (main=0x55555591ec40 <main>, argc=2, argv=0x7fffffffdb78, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
    stack_end=0x7fffffffdb68) at ../csu/libc-start.c:360
#24 0x00005555558354f5 in _start ()

Output from running with PYTHON_LLTRACE=4 PYTHON_OPT_DEBUG=4:
next_instr_abort_lltrace_opt_debug.txt

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.0a3+ (heads/main-dirty:fca7fec88ce, Jan 13 2026, 21:37:22) [Clang 21.1.2 (2ubuntu6)]

Linked PRs
  • gh-143894
  • gh-146324

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.