From: Mikhail Efimov Date: Thu, 13 Nov 2025 16:11:57 +0000 (+0300) Subject: [3.14] gh-140936: Fix JIT assertion crash at finalization if some generator is alive... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=48b7d75aaf0206c80813c3325fd4021cd6b99e2b;p=thirdparty%2FPython%2Fcpython.git [3.14] gh-140936: Fix JIT assertion crash at finalization if some generator is alive (GH-140969) (GH-141494) gh-140936: Fix JIT assertion crash at finalization if some generator is alive (GH-140969) --- diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index c74c8ee0eef8..1860325cba61 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1972,6 +1972,26 @@ class TestUopsOptimization(unittest.TestCase): assert ex is not None """)) + def test_interpreter_finalization_with_generator_alive(self): + script_helper.assert_python_ok("-c", textwrap.dedent(""" + import sys + t = tuple(range(%d)) + def simple_for(): + for x in t: + x + + def gen(): + try: + yield + except: + simple_for() + + sys.settrace(lambda *args: None) + simple_for() + g = gen() + next(g) + """ % _testinternalcapi.SPECIALIZATION_THRESHOLD)) + def global_identity(x): return x diff --git a/Python/optimizer.c b/Python/optimizer.c index e2b6adfab595..6679eecd648a 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -116,7 +116,14 @@ _PyOptimizer_Optimize( _PyExecutorObject **executor_ptr, int chain_depth) { _PyStackRef *stack_pointer = frame->stackpointer; - assert(_PyInterpreterState_GET()->jit); + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (!interp->jit) { + // gh-140936: It is possible that interp->jit will become false during + // interpreter finalization. However, the specialized JUMP_BACKWARD_JIT + // instruction may still be present. In this case, we should + // return immediately without optimization. + return 0; + } // The first executor in a chain and the MAX_CHAIN_DEPTH'th executor *must* // make progress in order to avoid infinite loops or excessively-long // side-exit chains. We can only insert the executor into the bytecode if