Skip to content

JIT: Assertion failure in _PyOptimizer_Optimize #143123

Closed

Description

@devdanzin

Crash report

What happened?

It's possible to abort a patched debug JIT build by running the code below. The interpreter must be called from a venv in which lafleur is installed as editable, likely due to that priming the GC into a state suitable for the crash.

Sorry about the convoluted reproduction steps.

The necessary patch is:

diff --git a/Include/internal/pycore_backoff.h b/Include/internal/pycore_backoff.h
index 23ca7299e0d..0289b5fee7c 100644
--- a/Include/internal/pycore_backoff.h
+++ b/Include/internal/pycore_backoff.h
@@ -124,7 +124,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(void)
@@ -137,7 +137,7 @@ initial_jump_backoff_counter(void)
  * 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

To install lafleur as editable, first create a venv and activate it, then clone the lafleur repo and run pip install -e /path/to/lafleur/clone.

This MRE must be invoked like this:

/path/to/venv/with/editable/lafleur/install/bin/python mre.py

MRE:

import asyncio
any_v2 = None
tuple_v4 = (1, "")

def f1():
    class A:
        def _():...
        def __(): ...
        def ___():...

    class B: ...
    class C:
        def _(): ...    
    class D:
        def _(): ...    
    class E:
        def _(): ...    
    class F:
        def _(): ...    
    class G:
        def _(): ...    
    class H:
        def _(): ...    
    
    l = []
    for i in range(5):
        def _(): ...
    class I:
        async def _(): ...
        try:
            c = _()
        except Exception: ...

    def __(): ...
    class J:
        def _(): ...

    for _ in range(300):
        try:
            try: ValueError("")
            except E: ...
        except Exception: ...
    (
        any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2,
        any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2,
        any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2,
        any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2,
        any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2,
        any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2,
        any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2, any_v2,
        any_v2, any_v2, 
    )
    class K:
        def _():...
        def __(): ...
        def ___():...
    class AsyncCtx_9078:
        def _(self): ...
        async def __():
            try:
                for _ in K(10): ...
            except Exception: ...
        try:
            c = __()
        except Exception: ...
    x, *y = tuple_v4
    class L:
        def _():...
        def __(): ...
        def ___():...
    class M:
        def _(self): ...
        async def __():
            try:
                for _ in L(10): ...
            except Exception: ...
        try:
            c = __()
        except Exception: ...

    x, *y = x, *y = tuple_v4
    class M:
        def _():...
        def __(): ...
        def ___():...
    class N:
        def _():...
        def __(): ...
        def ___():...
    class O:
        def _(self): ...
        async def __():
            try:
                for _ in N(10): ...
            except Exception: ...
        try:
            c = __()
        except Exception: ...
    class P:
        def _():...
        def __(): ...
        def ___():...
    class Q:
        def _(self): ...
        async def __():
            try:
                with Q(): ...
            except Exception: ...
        try:
            c = __()
        except Exception: ...
    class R:
        def _(self): ...
        async def __():
            try:
                with R(): ...
            except Exception: ...
        try:
            c = __()
        except Exception: ...

    x, *y = x, *y = tuple_v4
    class S:
        def __init__(self, lit):
            selit = self.count = 0
        def __aiter__(self):return self
        async def __anext__(self):
            if self.count: n
            self.count += 1
    class T:
        def _(self): ...
        async def __():
            try:
                async for _ in S(10): ...
            except Exception: ...
        try:
            c = __()
            while True:
                try: c.send(None)
                except Exception: break
        except Exception: ...

for i in range(300):
    print(i)
    f1()

Traceback:

1
[...]
200
201
python: Python/optimizer.c:144: int _PyOptimizer_Optimize(_PyInterpreterFrame *, PyThreadState *): Assertion `_tstate->jit_tracer_state.initial_state.func != NULL' 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  0x00005555563c0bd0 in _PyOptimizer_Optimize (frame=frame@entry=0x7e8ff6de5298, tstate=tstate@entry=0x555556e62830 <_PyRuntime+358864>) at Python/optimizer.c:144
#8  0x0000555555ed2e64 in stop_tracing_and_jit (tstate=0x555556e62830 <_PyRuntime+358864>, frame=frame@entry=0x7e8ff6de5298) at Python/ceval.c:1405
#9  0x0000555555e8eeed in _PyEval_EvalFrameDefault (tstate=<optimized out>, frame=<optimized out>, throwflag=<optimized out>) at Python/generated_cases.c.h:11628
#10 0x0000555555e6bf98 in _PyEval_EvalFrame (tstate=0x555556e62830 <_PyRuntime+358864>, frame=0x7e8ff6de5220, throwflag=0) at ./Include/internal/pycore_ceval.h:119
#11 _PyEval_Vector (tstate=<optimized out>, func=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kwnames=0x0) at Python/ceval.c:2483
#12 0x0000555555e6b9b5 in PyEval_EvalCode (co=<optimized out>, globals=<optimized out>, locals=0x7c7ff6e86440) at Python/ceval.c:1008

Output from running with PYTHON_LLTRACE=4 PYTHON_OPT_DEBUG=4:
830_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:3cc57505e53, Dec 23 2025, 19:04:15) [Clang 21.1.2 (2ubuntu6)]

Linked PRs

Activity

  1. added
    type-crashA hard crash of the interpreter, possibly with a core dump
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    on Dec 23, 2025
  2. Fidget-Spinner commented on Dec 23, 2025

    @Fidget-Spinner
    Member

    Can you try on current main please? Mark just fixed a GC problem with the executors a few hours ago.

  3. devdanzin commented on Dec 23, 2025

    @devdanzin
    MemberAuthor

    Yup, it's fixed on current main.

  4. devdanzin commented on Dec 23, 2025

    @devdanzin
    MemberAuthor

    Nope, I tested an unpatched build. It still aborts on current main with a correctly patched build.

  5. Fidget-Spinner commented on Dec 23, 2025

    @Fidget-Spinner
    Member

    @devdanzin can you see if it's fixed by this #143126 please ?

  6. devdanzin commented on Dec 23, 2025

    @devdanzin
    MemberAuthor

    Yes, that fixes it. I've double checked that I ran the right build this time and confirmed the fix.

  7. Fidget-Spinner commented on Dec 25, 2025

    @Fidget-Spinner
    Member

    @devdanzin sorry to bother you, could you please check again on the branch of the latest fix? I updated the PR to try a slightly different approach. Thanks!

  8. devdanzin commented on Dec 25, 2025

    @devdanzin
    MemberAuthor

    No bother at all, happy to help :)

    The new approach works too, no assertion failure with the PR applied.

  9. devdanzin commented on Jan 9, 2026

    @devdanzin
    MemberAuthor

    #143126 also fixes the same issue with the MRE from #143610, an obvious duplicate I reported by mistake.

  10. Fidget-Spinner commented on Jan 9, 2026

    @Fidget-Spinner
    Member

    @devdanzin i just updated the PR, could you please try again?

  11. devdanzin commented on Jan 9, 2026

    @devdanzin
    MemberAuthor

    @Fidget-Spinner: It fixes the assertion failure after you update too.

  12. added a commit that references this issue on Jan 14, 2026
  13. added a commit that references this issue on Feb 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    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