Skip to content

Commit 3af62d9

Browse files
[3.15] gh-156114: Fix crash in perf trampoline with unencodable code names (GH-156300) (#157773)
1 parent 7694e18 commit 3af62d9

4 files changed

Lines changed: 26 additions & 0 deletions

File tree

Lib/test/test_perf_profiler.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,16 @@ def baz():
113113
"Address should contain only hex characters",
114114
)
115115

116+
@unittest.skipIf(support.check_bolt_optimized(), "fails on BOLT instrumented binaries")
117+
def test_trampoline_with_unencodable_name(self):
118+
code = """if 1:
119+
import sys
120+
121+
sys.activate_stack_trampoline("perf")
122+
eval(compile("pass", "bad\\ud800file", "exec"))
123+
"""
124+
assert_python_ok("-c", code, PYTHON_JIT="0")
125+
116126
@unittest.skipIf(support.check_bolt_optimized(), "fails on BOLT instrumented binaries")
117127
def test_trampoline_works_with_forks(self):
118128
code = """if 1:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a crash in the perf trampoline when a code object has a name or filename
2+
that cannot be encoded to UTF-8. Patched by Shamil Abdulaev.

Python/perf_jit_trampoline.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,9 +749,15 @@ static void perf_map_jit_write_entry(void *state, const void *code_addr,
749749
if (co != NULL) {
750750
if (co->co_qualname != NULL) {
751751
entry = PyUnicode_AsUTF8(co->co_qualname);
752+
if (entry == NULL) {
753+
PyErr_Clear();
754+
}
752755
}
753756
if (co->co_filename != NULL) {
754757
filename = PyUnicode_AsUTF8(co->co_filename);
758+
if (filename == NULL) {
759+
PyErr_Clear();
760+
}
755761
}
756762
}
757763
perf_map_jit_write_entry_with_name(state, code_addr, code_size,

Python/perf_trampoline.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,18 @@ perf_map_write_entry(void *state, const void *code_addr,
254254
const char *entry = "";
255255
if (co->co_qualname != NULL) {
256256
entry = PyUnicode_AsUTF8(co->co_qualname);
257+
if (entry == NULL) {
258+
PyErr_Clear();
259+
entry = "";
260+
}
257261
}
258262
const char *filename = "";
259263
if (co->co_filename != NULL) {
260264
filename = PyUnicode_AsUTF8(co->co_filename);
265+
if (filename == NULL) {
266+
PyErr_Clear();
267+
filename = "";
268+
}
261269
}
262270
size_t perf_map_entry_size = snprintf(NULL, 0, "py::%s:%s", entry, filename) + 1;
263271
char* perf_map_entry = (char*) PyMem_RawMalloc(perf_map_entry_size);

0 commit comments

Comments
 (0)