Skip to content

Commit b53b0c1

Browse files
gh-135608: Add a null check for attribute promotion to fix a JIT crash (GH-135613)
Co-authored-by: devdanzin <[email protected]>
1 parent c8c13f8 commit b53b0c1

File tree

5 files changed

+48
-2
lines changed

5 files changed

+48
-2
lines changed

Lib/test/test_capi/test_opt.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,6 +2319,36 @@ def testfunc(n):
23192319
self.assertNotIn("_GUARD_TOS_INT", uops)
23202320
self.assertNotIn("_GUARD_NOS_INT", uops)
23212321

2322+
def test_attr_promotion_failure(self):
2323+
# We're not testing for any specific uops here, just
2324+
# testing it doesn't crash.
2325+
script_helper.assert_python_ok('-c', textwrap.dedent("""
2326+
import _testinternalcapi
2327+
import _opcode
2328+
import email
2329+
2330+
def get_first_executor(func):
2331+
code = func.__code__
2332+
co_code = code.co_code
2333+
for i in range(0, len(co_code), 2):
2334+
try:
2335+
return _opcode.get_executor(code, i)
2336+
except ValueError:
2337+
pass
2338+
return None
2339+
2340+
def testfunc(n):
2341+
for _ in range(n):
2342+
email.jit_testing = None
2343+
prompt = email.jit_testing
2344+
del email.jit_testing
2345+
2346+
2347+
testfunc(_testinternalcapi.TIER2_THRESHOLD)
2348+
ex = get_first_executor(testfunc)
2349+
assert ex is not None
2350+
"""))
2351+
23222352

23232353
def global_identity(x):
23242354
return x
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a crash in the JIT involving attributes of modules.

Python/optimizer_analysis.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj, bool pop)
103103
if ((int)index >= dict->ma_keys->dk_nentries) {
104104
return NULL;
105105
}
106+
PyDictKeysObject *keys = dict->ma_keys;
107+
if (keys->dk_version != inst->operand0) {
108+
return NULL;
109+
}
106110
PyObject *res = entries[index].me_value;
107111
if (res == NULL) {
108112
return NULL;

Python/optimizer_bytecodes.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,13 @@ dummy_func(void) {
591591
PyDict_Watch(GLOBALS_WATCHER_ID, dict);
592592
_Py_BloomFilter_Add(dependencies, dict);
593593
PyObject *res = convert_global_to_const(this_instr, dict, true);
594-
attr = sym_new_const(ctx, res);
594+
if (res == NULL) {
595+
attr = sym_new_not_null(ctx);
596+
}
597+
else {
598+
attr = sym_new_const(ctx, res);
599+
}
600+
595601
}
596602
}
597603
}

Python/optimizer_cases.c.h

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

0 commit comments

Comments
 (0)