From 21371efd0d723e9f5826241e0874d4ddc8d513cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Rosenkr=C3=A4nzer?= Date: Wed, 28 Oct 2026 22:18:14 +0100 Subject: [PATCH 1/3] gh-160852: Re-read the bytecode after JIT stop_tracing stop_tracing_and_jit() can run a finalizer that invalidates the executor sampled as ENTER_EXECUTOR. Dispatching that stale opcode calls _PyJIT_Entry(NULL). --- .../2026-10-28-22-15-00.gh-issue-160852.st0pTr.rst | 2 ++ Python/bytecodes.c | 10 ++++++++++ 2 files changed, 12 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-10-28-22-15-00.gh-issue-160852.st0pTr.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-28-22-15-00.gh-issue-160852.st0pTr.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-28-22-15-00.gh-issue-160852.st0pTr.rst new file mode 100644 index 00000000000000..dcf86d6f06323e --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-28-22-15-00.gh-issue-160852.st0pTr.rst @@ -0,0 +1,2 @@ +Fix a crash in the experimental JIT when a finalizer invalidates an +executor while ``stop_tracing`` leaves the tracer. diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 42ad83daa1ea46..d6b25d5ad1b29e 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -6636,6 +6636,16 @@ dummy_func( LEAVE_TRACING(); int err = stop_tracing_and_jit(tstate, frame); ERROR_IF(err < 0); + /* stop_tracing_and_jit() can drop the last reference to a + temporary and run a finalizer. A ResourceWarning then writes + __warningregistry__ into a watched globals dict, and + executor_invalidate() restores this instruction and clears its + executor slot. Dispatching the ENTER_EXECUTOR opcode sampled + above calls _PyJIT_Entry(NULL). Keep any EXTENDED_ARG bits + already accumulated in oparg; only the low byte lives in the + code unit. */ + opcode = next_instr->op.code; + oparg = (oparg & ~255) | next_instr->op.arg; DISPATCH_GOTO_NON_TRACING(); #else Py_FatalError("JIT label executed in non-jit build."); From 0cd44660b1f1249562fc807c13fd0ef2e14017e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Rosenkr=C3=A4nzer?= Date: Wed, 28 Oct 2026 22:18:25 +0100 Subject: [PATCH 2/3] gh-160852: Regenerate tier1 cases for the stop_tracing re-read --- Python/generated_cases.c.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index ee9b64107bb9f2..2775d918e02416 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -13833,6 +13833,8 @@ JUMP_TO_LABEL(error); if (err < 0) { JUMP_TO_LABEL(error); } + opcode = next_instr->op.code; + oparg = (oparg & ~255) | next_instr->op.arg; DISPATCH_GOTO_NON_TRACING(); #else Py_FatalError("JIT label executed in non-jit build."); From 1d615e97c2cb9f5e487f681ced785546c5a6466b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Rosenkr=C3=A4nzer?= Date: Wed, 28 Oct 2026 22:23:58 +0100 Subject: [PATCH 3/3] gh-160852: Regenerate the tier1 test cases for stop_tracing --- Modules/_testinternalcapi/test_cases.c.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 8e7ba1f69553dd..10e1dfc91248b8 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -13836,6 +13836,8 @@ JUMP_TO_LABEL(error); if (err < 0) { JUMP_TO_LABEL(error); } + opcode = next_instr->op.code; + oparg = (oparg & ~255) | next_instr->op.arg; DISPATCH_GOTO_NON_TRACING(); #else Py_FatalError("JIT label executed in non-jit build.");