Skip to content

Commit 277a037

Browse files
authored
gh-145197: Fix JIT trace crash when recording function from cleared generator frame (GH-145220)
1 parent 56b7dc4 commit 277a037

File tree

6 files changed

+37
-10
lines changed

6 files changed

+37
-10
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_capi/test_opt.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4114,6 +4114,28 @@ def __init__(self, name):
41144114
PYTHON_JIT_SIDE_EXIT_INITIAL_VALUE="1")
41154115
self.assertEqual(result[0].rc, 0, result)
41164116

4117+
def test_for_iter_gen_cleared_frame_does_not_crash(self):
4118+
# See: https://github.com/python/cpython/issues/145197
4119+
result = script_helper.run_python_until_end('-c', textwrap.dedent("""
4120+
def g():
4121+
yield 1
4122+
yield 2
4123+
4124+
for _ in range(4002):
4125+
for _ in g():
4126+
pass
4127+
4128+
for i in range(4002):
4129+
it = g()
4130+
if (i & 7) == 0:
4131+
next(it)
4132+
it.close()
4133+
for _ in it:
4134+
pass
4135+
"""),
4136+
PYTHON_JIT="1", PYTHON_JIT_STRESS="1")
4137+
self.assertEqual(result[0].rc, 0, result)
4138+
41174139
def global_identity(x):
41184140
return x
41194141

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix JIT trace crash when recording function from cleared generator frame.

Python/bytecodes.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5730,8 +5730,11 @@ dummy_func(
57305730
tier2 op(_RECORD_NOS_GEN_FUNC, (nos, tos -- nos, tos)) {
57315731
PyObject *obj = PyStackRef_AsPyObjectBorrow(nos);
57325732
if (PyGen_Check(obj)) {
5733-
PyObject *func = (PyObject *)_PyFrame_GetFunction(&((PyGenObject *)obj)->gi_iframe);
5734-
RECORD_VALUE(func);
5733+
PyGenObject *gen = (PyGenObject *)obj;
5734+
_PyStackRef func = gen->gi_iframe.f_funcobj;
5735+
if (!PyStackRef_IsNull(func)) {
5736+
RECORD_VALUE(PyStackRef_AsPyObjectBorrow(func));
5737+
}
57355738
}
57365739
}
57375740

Python/record_functions.c.h

Lines changed: 6 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)