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