From 9412a874a765da1241f9ea7c1fb689152d155004 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 18 Sep 2023 08:40:51 -0700 Subject: [3.12] gh-109371: Fix monitoring with instruction events set (gh-109385) (#109542) gh-109371: Fix monitoring with instruction events set (gh-109385) (cherry picked from commit 412f5e85d6b9f2e90c57c54539d06c7a025a472a) Co-authored-by: Tian Gao --- Lib/test/test_monitoring.py | 16 ++++++++++++++++ Lib/test/test_sys_setprofile.py | 13 ++++++++++++- .../2023-09-13-21-04-04.gh-issue-109371.HPEJr8.rst | 1 + Python/instrumentation.c | 5 ++++- 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-09-13-21-04-04.gh-issue-109371.HPEJr8.rst diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py index d091572..8c9755d 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -501,6 +501,22 @@ class MultipleMonitorsTest(MonitoringTestBase, unittest.TestCase): self.assertEqual(sys.monitoring._all_events(), {}) sys.monitoring.restart_events() + def test_with_instruction_event(self): + """Test that the second tool can set events with instruction events set by the first tool.""" + def f(): + pass + code = f.__code__ + + try: + self.assertEqual(sys.monitoring._all_events(), {}) + sys.monitoring.set_local_events(TEST_TOOL, code, E.INSTRUCTION | E.LINE) + sys.monitoring.set_local_events(TEST_TOOL2, code, E.LINE) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.set_events(TEST_TOOL2, 0) + self.assertEqual(sys.monitoring._all_events(), {}) + + class LineMonitoringTest(MonitoringTestBase, unittest.TestCase): def test_lines_single(self): diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index 49e076c..34c70d6 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -439,7 +439,6 @@ class TestEdgeCases(unittest.TestCase): sys.setprofile(foo) self.assertEqual(sys.getprofile(), bar) - def test_same_object(self): def foo(*args): ... @@ -448,6 +447,18 @@ class TestEdgeCases(unittest.TestCase): del foo sys.setprofile(sys.getprofile()) + def test_profile_after_trace_opcodes(self): + def f(): + ... + + sys._getframe().f_trace_opcodes = True + prev_trace = sys.gettrace() + sys.settrace(lambda *args: None) + f() + sys.settrace(prev_trace) + sys.setprofile(lambda *args: None) + f() + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-13-21-04-04.gh-issue-109371.HPEJr8.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-13-21-04-04.gh-issue-109371.HPEJr8.rst new file mode 100644 index 0000000..2fb18d5 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-09-13-21-04-04.gh-issue-109371.HPEJr8.rst @@ -0,0 +1 @@ +Deopted instructions correctly for tool initialization and modified the incorrect assertion in instrumentation, when a previous tool already sets INSTRUCTION events diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 0a54eb6..a6ff7a8 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -647,7 +647,7 @@ instrument(PyCodeObject *code, int i) if (opcode == INSTRUMENTED_INSTRUCTION) { opcode_ptr = &code->_co_monitoring->per_instruction_opcodes[i]; opcode = *opcode_ptr; - CHECK(!is_instrumented(opcode)); + CHECK(opcode != INSTRUMENTED_INSTRUCTION && opcode != INSTRUMENTED_LINE); CHECK(opcode == _PyOpcode_Deopt[opcode]); } CHECK(opcode != 0); @@ -1252,6 +1252,9 @@ initialize_tools(PyCodeObject *code) if (opcode == INSTRUMENTED_LINE) { opcode = code->_co_monitoring->lines[i].original_opcode; } + if (opcode == INSTRUMENTED_INSTRUCTION) { + opcode = code->_co_monitoring->per_instruction_opcodes[i]; + } bool instrumented = is_instrumented(opcode); if (instrumented) { opcode = DE_INSTRUMENT[opcode]; -- cgit v0.12