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