1""" 2Test that the Python operating system plugin works correctly 3""" 4 5 6import os 7import lldb 8from lldbsuite.test.lldbtest import * 9import lldbsuite.test.lldbutil as lldbutil 10 11 12class PluginPythonOSPlugin(TestBase): 13 NO_DEBUG_INFO_TESTCASE = True 14 15 def test_python_os_plugin(self): 16 """Test that the Python operating system plugin works correctly""" 17 self.build() 18 self.run_python_os_funcionality() 19 20 def run_python_os_step(self): 21 """Test that the Python operating system plugin works correctly when single stepping a virtual thread""" 22 self.build() 23 self.run_python_os_step() 24 25 def verify_os_thread_registers(self, thread): 26 frame = thread.GetFrameAtIndex(0) 27 registers = frame.GetRegisters().GetValueAtIndex(0) 28 reg_value = thread.GetThreadID() + 1 29 for reg in registers: 30 self.assertEqual( 31 reg.GetValueAsUnsigned(), 32 reg_value, 33 "Verify the registers contains the correct value", 34 ) 35 reg_value = reg_value + 1 36 37 def run_python_os_funcionality(self): 38 """Test that the Python operating system plugin works correctly""" 39 40 # Set debugger into synchronous mode 41 self.dbg.SetAsync(False) 42 43 # Create a target by the debugger. 44 exe = self.getBuildArtifact("a.out") 45 python_os_plugin_path = os.path.join(self.getSourceDir(), "operating_system.py") 46 target = self.dbg.CreateTarget(exe) 47 self.assertTrue(target, VALID_TARGET) 48 49 # Set breakpoints inside and outside methods that take pointers to the 50 # containing struct. 51 lldbutil.run_break_set_by_source_regexp(self, "// Set breakpoint here") 52 53 # Register our shared libraries for remote targets so they get 54 # automatically uploaded 55 arguments = None 56 environment = None 57 58 # Now launch the process, and do not stop at entry point. 59 process = target.LaunchSimple( 60 arguments, environment, self.get_process_working_directory() 61 ) 62 self.assertTrue(process, PROCESS_IS_VALID) 63 64 # Make sure there are no OS plug-in created thread when we first stop 65 # at our breakpoint in main 66 thread = process.GetThreadByID(0x111111111) 67 self.assertFalse( 68 thread.IsValid(), 69 "Make sure there is no thread 0x111111111 before we load the python OS plug-in", 70 ) 71 thread = process.GetThreadByID(0x222222222) 72 self.assertFalse( 73 thread.IsValid(), 74 "Make sure there is no thread 0x222222222 before we load the python OS plug-in", 75 ) 76 thread = process.GetThreadByID(0x333333333) 77 self.assertFalse( 78 thread.IsValid(), 79 "Make sure there is no thread 0x333333333 before we load the python OS plug-in", 80 ) 81 82 # Now load the python OS plug-in which should update the thread list and we should have 83 # OS plug-in created threads with the IDs: 0x111111111, 0x222222222, 84 # 0x333333333 85 command = ( 86 "settings set target.process.python-os-plugin-path '%s'" 87 % python_os_plugin_path 88 ) 89 self.dbg.HandleCommand(command) 90 91 # Verify our OS plug-in threads showed up 92 thread = process.GetThreadByID(0x111111111) 93 self.assertTrue( 94 thread.IsValid(), 95 "Make sure there is a thread 0x111111111 after we load the python OS plug-in", 96 ) 97 self.verify_os_thread_registers(thread) 98 thread = process.GetThreadByID(0x222222222) 99 self.assertTrue( 100 thread.IsValid(), 101 "Make sure there is a thread 0x222222222 after we load the python OS plug-in", 102 ) 103 self.verify_os_thread_registers(thread) 104 thread = process.GetThreadByID(0x333333333) 105 self.assertTrue( 106 thread.IsValid(), 107 "Make sure there is a thread 0x333333333 after we load the python OS plug-in", 108 ) 109 self.verify_os_thread_registers(thread) 110 111 # Now clear the OS plug-in path to make the OS plug-in created threads 112 # disappear 113 self.dbg.HandleCommand("settings clear target.process.python-os-plugin-path") 114 115 # Verify the threads are gone after unloading the python OS plug-in 116 thread = process.GetThreadByID(0x111111111) 117 self.assertFalse( 118 thread.IsValid(), 119 "Make sure there is no thread 0x111111111 after we unload the python OS plug-in", 120 ) 121 thread = process.GetThreadByID(0x222222222) 122 self.assertFalse( 123 thread.IsValid(), 124 "Make sure there is no thread 0x222222222 after we unload the python OS plug-in", 125 ) 126 thread = process.GetThreadByID(0x333333333) 127 self.assertFalse( 128 thread.IsValid(), 129 "Make sure there is no thread 0x333333333 after we unload the python OS plug-in", 130 ) 131 132 def run_python_os_step(self): 133 """Test that the Python operating system plugin works correctly and allows single stepping of a virtual thread that is backed by a real thread""" 134 135 # Set debugger into synchronous mode 136 self.dbg.SetAsync(False) 137 138 # Create a target by the debugger. 139 exe = self.getBuildArtifact("a.out") 140 python_os_plugin_path = os.path.join( 141 self.getSourceDir(), "operating_system2.py" 142 ) 143 target = self.dbg.CreateTarget(exe) 144 self.assertTrue(target, VALID_TARGET) 145 146 # Set breakpoints inside and outside methods that take pointers to the 147 # containing struct. 148 lldbutil.run_break_set_by_source_regexp(self, "// Set breakpoint here") 149 150 # Register our shared libraries for remote targets so they get 151 # automatically uploaded 152 arguments = None 153 environment = None 154 155 # Now launch the process, and do not stop at entry point. 156 process = target.LaunchSimple( 157 arguments, environment, self.get_process_working_directory() 158 ) 159 self.assertTrue(process, PROCESS_IS_VALID) 160 161 # Make sure there are no OS plug-in created thread when we first stop 162 # at our breakpoint in main 163 thread = process.GetThreadByID(0x111111111) 164 self.assertFalse( 165 thread.IsValid(), 166 "Make sure there is no thread 0x111111111 before we load the python OS plug-in", 167 ) 168 169 # Now load the python OS plug-in which should update the thread list and we should have 170 # OS plug-in created threads with the IDs: 0x111111111, 0x222222222, 171 # 0x333333333 172 command = ( 173 "settings set target.process.python-os-plugin-path '%s'" 174 % python_os_plugin_path 175 ) 176 self.dbg.HandleCommand(command) 177 178 # Verify our OS plug-in threads showed up 179 thread = process.GetThreadByID(0x111111111) 180 self.assertTrue( 181 thread.IsValid(), 182 "Make sure there is a thread 0x111111111 after we load the python OS plug-in", 183 ) 184 185 frame = thread.GetFrameAtIndex(0) 186 self.assertTrue( 187 frame.IsValid(), "Make sure we get a frame from thread 0x111111111" 188 ) 189 line_entry = frame.GetLineEntry() 190 191 self.assertEqual( 192 line_entry.GetFileSpec().GetFilename(), 193 "main.c", 194 "Make sure we stopped on line 5 in main.c", 195 ) 196 self.assertEqual( 197 line_entry.GetLine(), 5, "Make sure we stopped on line 5 in main.c" 198 ) 199 200 # Now single step thread 0x111111111 and make sure it does what we need 201 # it to 202 thread.StepOver() 203 204 frame = thread.GetFrameAtIndex(0) 205 self.assertTrue( 206 frame.IsValid(), "Make sure we get a frame from thread 0x111111111" 207 ) 208 line_entry = frame.GetLineEntry() 209 210 self.assertEqual( 211 line_entry.GetFileSpec().GetFilename(), 212 "main.c", 213 "Make sure we stepped from line 5 to line 6 in main.c", 214 ) 215 self.assertEqual( 216 line_entry.GetLine(), 217 6, 218 "Make sure we stepped from line 5 to line 6 in main.c", 219 ) 220