mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	gh-109371: Fix monitoring with instruction events set (gh-109385)
This commit is contained in:
		
							parent
							
								
									23f9f6f464
								
							
						
					
					
						commit
						412f5e85d6
					
				
					 4 changed files with 33 additions and 2 deletions
				
			
		| 
						 | 
					@ -501,6 +501,22 @@ def test_two_with_disable(self):
 | 
				
			||||||
            self.assertEqual(sys.monitoring._all_events(), {})
 | 
					            self.assertEqual(sys.monitoring._all_events(), {})
 | 
				
			||||||
            sys.monitoring.restart_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):
 | 
					class LineMonitoringTest(MonitoringTestBase, unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_lines_single(self):
 | 
					    def test_lines_single(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -439,7 +439,6 @@ def __del__(self):
 | 
				
			||||||
        sys.setprofile(foo)
 | 
					        sys.setprofile(foo)
 | 
				
			||||||
        self.assertEqual(sys.getprofile(), bar)
 | 
					        self.assertEqual(sys.getprofile(), bar)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def test_same_object(self):
 | 
					    def test_same_object(self):
 | 
				
			||||||
        def foo(*args):
 | 
					        def foo(*args):
 | 
				
			||||||
            ...
 | 
					            ...
 | 
				
			||||||
| 
						 | 
					@ -448,6 +447,18 @@ def foo(*args):
 | 
				
			||||||
        del foo
 | 
					        del foo
 | 
				
			||||||
        sys.setprofile(sys.getprofile())
 | 
					        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__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    unittest.main()
 | 
					    unittest.main()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Deopted instructions correctly for tool initialization and modified the incorrect assertion in instrumentation, when a previous tool already sets INSTRUCTION events
 | 
				
			||||||
| 
						 | 
					@ -664,7 +664,7 @@ instrument(PyCodeObject *code, int i)
 | 
				
			||||||
    if (opcode == INSTRUMENTED_INSTRUCTION) {
 | 
					    if (opcode == INSTRUMENTED_INSTRUCTION) {
 | 
				
			||||||
        opcode_ptr = &code->_co_monitoring->per_instruction_opcodes[i];
 | 
					        opcode_ptr = &code->_co_monitoring->per_instruction_opcodes[i];
 | 
				
			||||||
        opcode = *opcode_ptr;
 | 
					        opcode = *opcode_ptr;
 | 
				
			||||||
        CHECK(!is_instrumented(opcode));
 | 
					        CHECK(opcode != INSTRUMENTED_INSTRUCTION && opcode != INSTRUMENTED_LINE);
 | 
				
			||||||
        CHECK(opcode == _PyOpcode_Deopt[opcode]);
 | 
					        CHECK(opcode == _PyOpcode_Deopt[opcode]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    CHECK(opcode != 0);
 | 
					    CHECK(opcode != 0);
 | 
				
			||||||
| 
						 | 
					@ -1295,6 +1295,9 @@ initialize_tools(PyCodeObject *code)
 | 
				
			||||||
        if (opcode == INSTRUMENTED_LINE) {
 | 
					        if (opcode == INSTRUMENTED_LINE) {
 | 
				
			||||||
            opcode = code->_co_monitoring->lines[i].original_opcode;
 | 
					            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);
 | 
					        bool instrumented = is_instrumented(opcode);
 | 
				
			||||||
        if (instrumented) {
 | 
					        if (instrumented) {
 | 
				
			||||||
            opcode = DE_INSTRUMENT[opcode];
 | 
					            opcode = DE_INSTRUMENT[opcode];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue