1""" 2Test thread states. 3""" 4 5 6 7import unittest2 8import lldb 9from lldbsuite.test.decorators import * 10from lldbsuite.test.lldbtest import * 11from lldbsuite.test import lldbutil 12 13 14class ThreadStateTestCase(TestBase): 15 16 @expectedFailureAll( 17 oslist=["linux"], 18 bugnumber="llvm.org/pr15824 thread states not properly maintained") 19 @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237> 20 @expectedFailureAll( 21 oslist=["freebsd"], 22 bugnumber="llvm.org/pr18190 thread states not properly maintained") 23 @expectedFailureNetBSD 24 def test_state_after_breakpoint(self): 25 """Test thread state after breakpoint.""" 26 self.build() 27 self.thread_state_after_breakpoint_test() 28 29 @skipIfDarwin # 'llvm.org/pr23669', cause Python crash randomly 30 @expectedFailureAll( 31 oslist=lldbplatformutil.getDarwinOSTriples(), 32 bugnumber="llvm.org/pr23669") 33 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660") 34 def test_state_after_continue(self): 35 """Test thread state after continue.""" 36 self.build() 37 self.thread_state_after_continue_test() 38 39 @skipIfDarwin # 'llvm.org/pr23669', cause Python crash randomly 40 @expectedFailureDarwin('llvm.org/pr23669') 41 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660") 42 @expectedFailureNetBSD 43 # thread states not properly maintained 44 @expectedFailure("llvm.org/pr16712") 45 def test_state_after_expression(self): 46 """Test thread state after expression.""" 47 self.build() 48 self.thread_state_after_expression_test() 49 50 # thread states not properly maintained 51 @expectedFailure("llvm.org/pr15824 and <rdar://problem/28557237>") 52 @expectedFailureAll( 53 oslist=["windows"], 54 bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly") 55 @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237> 56 @expectedFailureNetBSD 57 def test_process_state(self): 58 """Test thread states (comprehensive).""" 59 self.build() 60 self.thread_states_test() 61 62 def setUp(self): 63 # Call super's setUp(). 64 TestBase.setUp(self) 65 # Find the line numbers for our breakpoints. 66 self.break_1 = line_number('main.cpp', '// Set first breakpoint here') 67 self.break_2 = line_number('main.cpp', '// Set second breakpoint here') 68 69 def thread_state_after_breakpoint_test(self): 70 """Test thread state after breakpoint.""" 71 exe = self.getBuildArtifact("a.out") 72 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 73 74 # This should create a breakpoint in the main thread. 75 bp = lldbutil.run_break_set_by_file_and_line( 76 self, "main.cpp", self.break_1, num_expected_locations=1) 77 78 # Run the program. 79 self.runCmd("run", RUN_SUCCEEDED) 80 81 # Get the target process 82 target = self.dbg.GetSelectedTarget() 83 process = target.GetProcess() 84 85 thread = lldbutil.get_stopped_thread( 86 process, lldb.eStopReasonBreakpoint) 87 self.assertIsNotNone(thread) 88 89 # Make sure the thread is in the stopped state. 90 self.assertTrue( 91 thread.IsStopped(), 92 "Thread state isn't \'stopped\' during breakpoint 1.") 93 self.assertFalse(thread.IsSuspended(), 94 "Thread state is \'suspended\' during breakpoint 1.") 95 96 # Kill the process 97 self.runCmd("process kill") 98 99 def wait_for_running_event(self, process): 100 listener = self.dbg.GetListener() 101 if lldb.remote_platform: 102 lldbutil.expect_state_changes( 103 self, listener, process, [ 104 lldb.eStateConnected]) 105 lldbutil.expect_state_changes( 106 self, listener, process, [ 107 lldb.eStateRunning]) 108 109 def thread_state_after_continue_test(self): 110 """Test thread state after continue.""" 111 exe = self.getBuildArtifact("a.out") 112 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 113 114 # This should create a breakpoint in the main thread. 115 lldbutil.run_break_set_by_file_and_line( 116 self, "main.cpp", self.break_1, num_expected_locations=1) 117 lldbutil.run_break_set_by_file_and_line( 118 self, "main.cpp", self.break_2, num_expected_locations=1) 119 120 # Run the program. 121 self.runCmd("run", RUN_SUCCEEDED) 122 123 # Get the target process 124 target = self.dbg.GetSelectedTarget() 125 process = target.GetProcess() 126 127 thread = lldbutil.get_stopped_thread( 128 process, lldb.eStopReasonBreakpoint) 129 self.assertIsNotNone(thread) 130 131 # Continue, the inferior will go into an infinite loop waiting for 132 # 'g_test' to change. 133 self.dbg.SetAsync(True) 134 self.runCmd("continue") 135 self.wait_for_running_event(process) 136 137 # Check the thread state. It should be running. 138 self.assertFalse( 139 thread.IsStopped(), 140 "Thread state is \'stopped\' when it should be running.") 141 self.assertFalse( 142 thread.IsSuspended(), 143 "Thread state is \'suspended\' when it should be running.") 144 145 # Go back to synchronous interactions 146 self.dbg.SetAsync(False) 147 148 # Kill the process 149 self.runCmd("process kill") 150 151 def thread_state_after_expression_test(self): 152 """Test thread state after expression.""" 153 exe = self.getBuildArtifact("a.out") 154 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 155 156 # This should create a breakpoint in the main thread. 157 lldbutil.run_break_set_by_file_and_line( 158 self, "main.cpp", self.break_1, num_expected_locations=1) 159 lldbutil.run_break_set_by_file_and_line( 160 self, "main.cpp", self.break_2, num_expected_locations=1) 161 162 # Run the program. 163 self.runCmd("run", RUN_SUCCEEDED) 164 165 # Get the target process 166 target = self.dbg.GetSelectedTarget() 167 process = target.GetProcess() 168 169 thread = lldbutil.get_stopped_thread( 170 process, lldb.eStopReasonBreakpoint) 171 self.assertIsNotNone(thread) 172 173 # Get the inferior out of its loop 174 self.runCmd("expression g_test = 1") 175 176 # Check the thread state 177 self.assertTrue( 178 thread.IsStopped(), 179 "Thread state isn't \'stopped\' after expression evaluation.") 180 self.assertFalse( 181 thread.IsSuspended(), 182 "Thread state is \'suspended\' after expression evaluation.") 183 184 # Let the process run to completion 185 self.runCmd("process continue") 186 187 @expectedFailureAll( 188 oslist=["windows"], 189 bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly") 190 @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237> 191 @no_debug_info_test 192 def test_process_interrupt(self): 193 """Test process interrupt and continue.""" 194 self.build() 195 exe = self.getBuildArtifact("a.out") 196 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 197 198 # This should create a breakpoint in the main thread. 199 bpno = lldbutil.run_break_set_by_file_and_line( 200 self, "main.cpp", self.break_1, num_expected_locations=1) 201 202 # Run the program. 203 self.runCmd("run", RUN_SUCCEEDED) 204 205 # Get the target process 206 target = self.dbg.GetSelectedTarget() 207 process = target.GetProcess() 208 209 thread = lldbutil.get_stopped_thread( 210 process, lldb.eStopReasonBreakpoint) 211 self.assertIsNotNone(thread) 212 213 # Remove the breakpoint to avoid the single-step-over-bkpt dance in the 214 # "continue" below 215 self.assertTrue(target.BreakpointDelete(bpno)) 216 217 # Continue, the inferior will go into an infinite loop waiting for 218 # 'g_test' to change. 219 self.dbg.SetAsync(True) 220 self.runCmd("continue") 221 self.wait_for_running_event(process) 222 223 # Go back to synchronous interactions 224 self.dbg.SetAsync(False) 225 226 # Stop the process 227 self.runCmd("process interrupt") 228 229 self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) 230 231 # Get the inferior out of its loop 232 self.runCmd("expression g_test = 1") 233 234 # Run to completion 235 self.runCmd("continue") 236 237 def thread_states_test(self): 238 """Test thread states (comprehensive).""" 239 exe = self.getBuildArtifact("a.out") 240 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 241 242 # This should create a breakpoint in the main thread. 243 lldbutil.run_break_set_by_file_and_line( 244 self, "main.cpp", self.break_1, num_expected_locations=1) 245 lldbutil.run_break_set_by_file_and_line( 246 self, "main.cpp", self.break_2, num_expected_locations=1) 247 248 # Run the program. 249 self.runCmd("run", RUN_SUCCEEDED) 250 251 # Get the target process 252 target = self.dbg.GetSelectedTarget() 253 process = target.GetProcess() 254 thread = lldbutil.get_stopped_thread( 255 process, lldb.eStopReasonBreakpoint) 256 self.assertIsNotNone(thread) 257 258 # Make sure the thread is in the stopped state. 259 self.assertTrue( 260 thread.IsStopped(), 261 "Thread state isn't \'stopped\' during breakpoint 1.") 262 self.assertFalse(thread.IsSuspended(), 263 "Thread state is \'suspended\' during breakpoint 1.") 264 265 # Continue, the inferior will go into an infinite loop waiting for 266 # 'g_test' to change. 267 self.dbg.SetAsync(True) 268 self.runCmd("continue") 269 self.wait_for_running_event(process) 270 271 # Check the thread state. It should be running. 272 self.assertFalse( 273 thread.IsStopped(), 274 "Thread state is \'stopped\' when it should be running.") 275 self.assertFalse( 276 thread.IsSuspended(), 277 "Thread state is \'suspended\' when it should be running.") 278 279 # Go back to synchronous interactions 280 self.dbg.SetAsync(False) 281 282 # Stop the process 283 self.runCmd("process interrupt") 284 285 self.assertEqual(thread.GetState(), lldb.eStopReasonSignal) 286 287 # Check the thread state 288 self.assertTrue( 289 thread.IsStopped(), 290 "Thread state isn't \'stopped\' after process stop.") 291 self.assertFalse(thread.IsSuspended(), 292 "Thread state is \'suspended\' after process stop.") 293 294 # Get the inferior out of its loop 295 self.runCmd("expression g_test = 1") 296 297 # Check the thread state 298 self.assertTrue( 299 thread.IsStopped(), 300 "Thread state isn't \'stopped\' after expression evaluation.") 301 self.assertFalse( 302 thread.IsSuspended(), 303 "Thread state is \'suspended\' after expression evaluation.") 304 305 self.assertEqual(thread.GetState(), lldb.eStopReasonSignal) 306 307 # Run to breakpoint 2 308 self.runCmd("continue") 309 310 self.assertEqual(thread.GetState(), lldb.eStopReasonBreakpoint) 311 312 # Make sure both threads are stopped 313 self.assertTrue( 314 thread.IsStopped(), 315 "Thread state isn't \'stopped\' during breakpoint 2.") 316 self.assertFalse(thread.IsSuspended(), 317 "Thread state is \'suspended\' during breakpoint 2.") 318 319 # Run to completion 320 self.runCmd("continue") 321 322 # At this point, the inferior process should have exited. 323 self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED) 324