Skip to content

JIT: Segfault from setting UOP_MAX_TRACE_LENGTH to a large value #143751

@devdanzin

Description

@devdanzin

Crash report

What happened?

A JIT build with the patch below applied will frequently segfault. A way to reproduce is to start an interpreter (with PyREPL) and hold the space key.

The 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
diff --git a/Include/internal/pycore_uop.h b/Include/internal/pycore_uop.h
index e828a1cc5a5..538bd3bc630 100644
--- a/Include/internal/pycore_uop.h
+++ b/Include/internal/pycore_uop.h
@@ -38,9 +38,9 @@ typedef struct _PyUOpInstruction{
 // This is the length of the trace we translate initially.
 #ifdef Py_DEBUG
     // With asserts, the stencils are a lot larger
-#define UOP_MAX_TRACE_LENGTH 2000
+#define UOP_MAX_TRACE_LENGTH 8000
 #else
-#define UOP_MAX_TRACE_LENGTH 5000
+#define UOP_MAX_TRACE_LENGTH 8000
 #endif
 #define UOP_BUFFER_SIZE (UOP_MAX_TRACE_LENGTH * sizeof(_PyUOpInstruction))
 

Backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x0000555556406cd4 in _Py_ExecutorDetach (executor=executor@entry=0x7ebff6e30220) at Python/optimizer.c:1762
1762        assert(instruction->op.code == ENTER_EXECUTOR);

#0  0x0000555556406cd4 in _Py_ExecutorDetach (executor=executor@entry=0x7ebff6e30220) at Python/optimizer.c:1762
#1  0x0000555556407bf3 in executor_invalidate (op=0x7ebff6e30220) at Python/optimizer.c:1786
#2  0x000055555640177e in uop_dealloc (op=0x7ebff6e30280) at Python/optimizer.c:342
#3  0x0000555555c1e067 in _Py_Dealloc (op=op@entry=0x7ebff6e30220) at Objects/object.c:3207
#4  0x00005555563fe83c in Py_DECREF (lineno=1415, op=0x7ebff6e30220, filename=<optimized out>) at ./Include/refcount.h:403
#5  make_executor_from_uops (buffer=<optimized out>, length=1246, dependencies=0x7bfff5806870, tstate=<optimized out>) at Python/optimizer.c:1415
#6  uop_optimize (frame=0x7e8ff6de5928, tstate=<optimized out>, progress_needed=true, exec_ptr=<optimized out>) at Python/optimizer.c:1532
#7  _PyOptimizer_Optimize (frame=frame@entry=0x7e8ff6de5928, tstate=tstate@entry=0x555556ed1d70 <_PyRuntime+359408>) at Python/optimizer.c:170
#8  0x0000555555ed98c4 in stop_tracing_and_jit (tstate=0x555556ed1d70 <_PyRuntime+359408>, frame=frame@entry=0x7e8ff6de5928) at Python/ceval.c:1461
#9  0x0000555555e922c0 in _PyEval_EvalFrameDefault (tstate=<optimized out>, frame=<optimized out>, throwflag=<optimized out>) at Python/generated_cases.c.h:12450
#10 0x0000555555e72c88 in _PyEval_EvalFrame (tstate=0x555556ed1d70 <_PyRuntime+359408>, frame=0x7e8ff6de5220, throwflag=0) at ./Include/internal/pycore_ceval.h:118
#11 _PyEval_Vector (tstate=<optimized out>, func=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kwnames=0x7c7ff6f692c0) at Python/ceval.c:2541
#12 0x0000555555ae3814 in _PyVectorcall_Call (tstate=<optimized out>, func=<optimized out>, callable=<optimized out>, tuple=0x555556e9ae60 <_PyRuntime+134368>, kwargs=<optimized out>)
at Objects/call.c:285
#13 0x0000555556511505 in pymain_start_pyrepl (pythonstartup=<optimized out>) at Modules/main.c:310
#14 0x0000555556510a15 in pymain_run_stdin (config=<optimized out>) at Modules/main.c:570
#15 0x000055555650e21b in pymain_run_python (exitcode=0x7bfff5c1e500) at Modules/main.c:694
#16 Py_RunMain () at Modules/main.c:772
#17 0x000055555650f117 in pymain_main (args=<optimized out>) at Modules/main.c:802
#18 0x000055555650f288 in Py_BytesMain (argc=<optimized out>, argv=0x7fffffffdc08) at Modules/main.c:826
#19 0x00007ffff7c2a575 in __libc_start_call_main (main=main@entry=0x55555591ec40 <main>, argc=argc@entry=1, argv=argv@entry=0x7fffffffdc08) at ../sysdeps/nptl/libc_start_call_main.h:58
#20 0x00007ffff7c2a628 in __libc_start_main_impl (main=0x55555591ec40 <main>, argc=1, argv=0x7fffffffdc08, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffdbf8) at ../csu/libc-start.c:360
#21 0x00005555558354f5 in _start ()

Output from running with PYTHON_OPT_DEBUG=4 and PYTHON_LLTRACE=4.
uop_max_trace_length_lltrace_opt_debug.txt

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:43c76587c1b, Jan 12 2026, 16:22:56) [Clang 21.1.2 (2ubuntu6)]

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