88
99JIT_SAMPLE_SCRIPT = os .path .join (os .path .dirname (__file__ ), "gdb_jit_sample.py" )
1010# In batch GDB, break in builtin_id() while it is running under JIT,
11- # then repeatedly "finish" until the selected frame is the executor .
12- # That gives a deterministic backtrace starting with py::jit_executor :<jit>.
11+ # then repeatedly "finish" until the selected frame is the JIT entry .
12+ # That gives a deterministic backtrace starting with py::jit_entry :<jit>.
1313#
14- # builtin_id() sits only a few helper frames above the executor on this path.
14+ # builtin_id() sits only a few helper frames above the JIT entry on this path.
1515# This bound is just a generous upper limit so the test fails clearly if the
1616# expected stack shape changes.
1717MAX_FINISH_STEPS = 20
1818# Break directly on the lazy shim entry in the binary, then single-step just
19- # enough to let it install the compiled shim and set a temporary breakpoint on
20- # the resulting JIT entry address.
21- MAX_SHIM_SETUP_STEPS = 20
22- # After landing on the executor frame, single-step a little further into the
23- # blob so the backtrace is taken from executor code itself rather than the
19+ # enough to let it install the compiled JIT entry and set a temporary
20+ # breakpoint on the resulting address.
21+ MAX_ENTRY_SETUP_STEPS = 20
22+ # After landing on the JIT entry frame, single-step a little further into the
23+ # blob so the backtrace is taken from JIT code itself rather than the
2424# immediate helper-return site.
25- EXECUTOR_SINGLE_STEPS = 2
25+ JIT_ENTRY_SINGLE_STEPS = 2
2626EVAL_FRAME_RE = r"(_PyEval_EvalFrameDefault|_PyEval_Vector)"
2727
28- FINISH_TO_JIT_EXECUTOR = (
28+ FINISH_TO_JIT_ENTRY = (
2929 "python exec(\" import gdb\\ n"
30- "target = 'py::jit_executor :<jit>'\\ n"
30+ "target = 'py::jit_entry :<jit>'\\ n"
3131 f"for _ in range({ MAX_FINISH_STEPS } ):\\ n"
3232 " frame = gdb.selected_frame()\\ n"
3333 " if frame is not None and frame.name() == target:\\ n"
3636 "else:\\ n"
3737 " raise RuntimeError('did not reach %s' % target)\\ n\" )"
3838)
39- BREAK_IN_COMPILED_SHIM = (
39+ BREAK_IN_COMPILED_JIT_ENTRY = (
4040 "python exec(\" import gdb\\ n"
4141 "lazy = int(gdb.parse_and_eval('(void*)_Py_LazyJitShim'))\\ n"
42- f"for _ in range({ MAX_SHIM_SETUP_STEPS } ):\\ n"
42+ f"for _ in range({ MAX_ENTRY_SETUP_STEPS } ):\\ n"
4343 " entry = int(gdb.parse_and_eval('(void*)_Py_jit_entry'))\\ n"
4444 " if entry != lazy:\\ n"
4545 " gdb.execute('tbreak *0x%x' % entry)\\ n"
4646 " break\\ n"
4747 " gdb.execute('next')\\ n"
4848 "else:\\ n"
49- " raise RuntimeError('compiled shim was not installed')\\ n\" )"
49+ " raise RuntimeError('compiled JIT entry was not installed')\\ n\" )"
5050)
5151
5252
@@ -59,21 +59,23 @@ def setUpModule():
5959 "requires a JIT-enabled build" ,
6060)
6161class JitBacktraceTests (DebuggerTests ):
62- def test_bt_shows_compiled_jit_shim (self ):
62+ def test_bt_shows_compiled_jit_entry (self ):
6363 gdb_output = self .get_stack_trace (
6464 script = JIT_SAMPLE_SCRIPT ,
6565 breakpoint = "_Py_LazyJitShim" ,
6666 cmds_after_breakpoint = [
67- BREAK_IN_COMPILED_SHIM ,
67+ BREAK_IN_COMPILED_JIT_ENTRY ,
6868 "continue" ,
6969 "bt" ,
7070 ],
7171 PYTHON_JIT = "1" ,
7272 )
73+ # GDB registers the compiled JIT entry and per-trace JIT regions under
74+ # the same synthetic symbol name.
7375 self .assertRegex (
7476 gdb_output ,
7577 re .compile (
76- rf"#0\s+py::jit_shim :<jit>.*{ EVAL_FRAME_RE } " ,
78+ rf"#0\s+py::jit_entry :<jit>.*{ EVAL_FRAME_RE } " ,
7779 re .DOTALL ,
7880 ),
7981 )
@@ -90,27 +92,27 @@ def test_bt_unwinds_through_jit_frames(self):
9092 self .assertRegex (
9193 gdb_output ,
9294 re .compile (
93- rf"py::jit_executor :<jit>.*{ EVAL_FRAME_RE } " ,
95+ rf"py::jit_entry :<jit>.*{ EVAL_FRAME_RE } " ,
9496 re .DOTALL ,
9597 ),
9698 )
9799
98- def test_bt_unwinds_from_inside_jit_executor (self ):
100+ def test_bt_unwinds_from_inside_jit_entry (self ):
99101 gdb_output = self .get_stack_trace (
100102 script = JIT_SAMPLE_SCRIPT ,
101103 cmds_after_breakpoint = [
102- FINISH_TO_JIT_EXECUTOR ,
103- * (["si" ] * EXECUTOR_SINGLE_STEPS ),
104+ FINISH_TO_JIT_ENTRY ,
105+ * (["si" ] * JIT_ENTRY_SINGLE_STEPS ),
104106 "bt" ,
105107 ],
106108 PYTHON_JIT = "1" ,
107109 )
108- # Once the selected PC is inside the executor , we only require that
110+ # Once the selected PC is inside the JIT entry , we only require that
109111 # GDB can identify the JIT frame and keep unwinding into _PyEval_*.
110112 self .assertRegex (
111113 gdb_output ,
112114 re .compile (
113- rf"#0\s+py::jit_executor :<jit>.*{ EVAL_FRAME_RE } " ,
115+ rf"#0\s+py::jit_entry :<jit>.*{ EVAL_FRAME_RE } " ,
114116 re .DOTALL ,
115117 ),
116118 )
0 commit comments