1 """ 2 Test thread states. 3 """ 4 5 import os, time 6 import unittest2 7 import lldb 8 from lldbtest import * 9 import lldbutil 10 11 class ThreadStateTestCase(TestBase): 12 13 mydir = os.path.join("functionalities", "thread", "state") 14 15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 16 @dsym_test 17 def test_state_after_breakpoint_with_dsym(self): 18 """Test thread state after breakpoint.""" 19 self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False)) 20 self.thread_state_after_breakpoint_test() 21 22 @dwarf_test 23 def test_state_after_breakpoint_with_dwarf(self): 24 """Test thread state after breakpoint.""" 25 self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False)) 26 self.thread_state_after_breakpoint_test() 27 28 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 29 @dsym_test 30 def test_state_after_continue_with_dsym(self): 31 """Test thread state after continue.""" 32 self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False)) 33 self.thread_state_after_continue_test() 34 35 @dwarf_test 36 def test_state_after_continue_with_dwarf(self): 37 """Test thread state after continue.""" 38 self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False)) 39 self.thread_state_after_continue_test() 40 41 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 42 @dsym_test 43 def test_state_after_expression_with_dsym(self): 44 """Test thread state after expression.""" 45 self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False)) 46 self.thread_state_after_continue_test() 47 48 @dwarf_test 49 def test_state_after_expression_with_dwarf(self): 50 """Test thread state after expression.""" 51 self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False)) 52 self.thread_state_after_continue_test() 53 54 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 55 @dsym_test 56 @unittest2.expectedFailure("llvm.org/pr16172") # thread states not properly maintained 57 def test_process_interrupt_with_dsym(self): 58 """Test process interrupt.""" 59 self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False)) 60 self.process_interrupt_test() 61 62 @dwarf_test 63 @unittest2.expectedFailure("llvm.org/pr16712") # thread states not properly maintained 64 def test_process_interrupt_with_dwarf(self): 65 """Test process interrupt.""" 66 self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False)) 67 self.process_interrupt_test() 68 69 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 70 @dsym_test 71 @unittest2.expectedFailure("llvm.org/pr15824") # thread states not properly maintained 72 def test_process_state_with_dsym(self): 73 """Test thread states (comprehensive).""" 74 self.buildDsym(dictionary=self.getBuildFlags(use_cpp11=False)) 75 self.thread_states_test() 76 77 @dwarf_test 78 @unittest2.expectedFailure("llvm.org/pr15824") # thread states not properly maintained 79 def test_process_state_with_dwarf(self): 80 """Test thread states (comprehensive).""" 81 self.buildDwarf(dictionary=self.getBuildFlags(use_cpp11=False)) 82 self.thread_states_test() 83 84 def setUp(self): 85 # Call super's setUp(). 86 TestBase.setUp(self) 87 # Find the line numbers for our breakpoints. 88 self.break_1 = line_number('main.c', '// Set first breakpoint here') 89 self.break_2 = line_number('main.c', '// Set second breakpoint here') 90 91 def thread_state_after_breakpoint_test(self): 92 """Test thread state after breakpoint.""" 93 exe = os.path.join(os.getcwd(), "a.out") 94 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 95 96 # This should create a breakpoint in the main thread. 97 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1) 98 99 # The breakpoint list should show 1 breakpoint with 1 location. 100 self.expect("breakpoint list -f", "Breakpoint location shown correctly", 101 substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1]) 102 103 # Run the program. 104 self.runCmd("run", RUN_SUCCEEDED) 105 106 # The stop reason of the thread should be breakpoint. 107 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 108 substrs = ['stopped', 109 '* thread #1', 110 'stop reason = breakpoint']) 111 112 # Get the target process 113 target = self.dbg.GetSelectedTarget() 114 process = target.GetProcess() 115 116 # Get the number of threads 117 num_threads = process.GetNumThreads() 118 119 self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.') 120 121 # Get the thread object 122 thread = process.GetThreadAtIndex(0) 123 124 # Make sure the thread is in the stopped state. 125 self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 1.") 126 self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 1.") 127 128 # Kill the process 129 self.runCmd("process kill") 130 131 def thread_state_after_continue_test(self): 132 """Test thread state after continue.""" 133 exe = os.path.join(os.getcwd(), "a.out") 134 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 135 136 # This should create a breakpoint in the main thread. 137 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1) 138 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_2, num_expected_locations=1) 139 140 # The breakpoint list should show 1 breakpoints with 1 location. 141 self.expect("breakpoint list -f", "Breakpoint location shown correctly", 142 substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1]) 143 144 # Run the program. 145 self.runCmd("run", RUN_SUCCEEDED) 146 147 # The stop reason of the thread should be breakpoint. 148 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 149 substrs = ['stopped', 150 '* thread #1', 151 'stop reason = breakpoint']) 152 153 # Get the target process 154 target = self.dbg.GetSelectedTarget() 155 process = target.GetProcess() 156 157 # Get the number of threads 158 num_threads = process.GetNumThreads() 159 160 self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.') 161 162 # Get the thread object 163 thread = process.GetThreadAtIndex(0) 164 165 # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change. 166 self.dbg.SetAsync(True) 167 self.runCmd("continue") 168 time.sleep(1) 169 170 # Check the thread state. It should be running. 171 self.assertFalse(thread.IsStopped(), "Thread state is \'stopped\' when it should be running.") 172 self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' when it should be running.") 173 174 # Go back to synchronous interactions 175 self.dbg.SetAsync(False) 176 177 # Kill the process 178 self.runCmd("process kill") 179 180 def thread_state_after_expression_test(self): 181 """Test thread state after expression.""" 182 exe = os.path.join(os.getcwd(), "a.out") 183 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 184 185 # This should create a breakpoint in the main thread. 186 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1) 187 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_2, num_expected_locations=1) 188 189 # The breakpoint list should show 1 breakpoints with 1 location. 190 self.expect("breakpoint list -f", "Breakpoint location shown correctly", 191 substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1]) 192 193 # Run the program. 194 self.runCmd("run", RUN_SUCCEEDED) 195 196 # The stop reason of the thread should be breakpoint. 197 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 198 substrs = ['stopped', 199 '* thread #1', 200 'stop reason = breakpoint']) 201 202 # Get the target process 203 target = self.dbg.GetSelectedTarget() 204 process = target.GetProcess() 205 206 # Get the number of threads 207 num_threads = process.GetNumThreads() 208 209 self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.') 210 211 # Get the thread object 212 thread = process.GetThreadAtIndex(0) 213 214 # Get the inferior out of its loop 215 self.runCmd("expression g_test = 1") 216 217 # Check the thread state 218 self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after expression evaluation.") 219 self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after expression evaluation.") 220 221 # Let the process run to completion 222 self.runCmd("process continue") 223 224 225 def process_interrupt_test(self): 226 """Test process interrupt and continue.""" 227 exe = os.path.join(os.getcwd(), "a.out") 228 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 229 230 # This should create a breakpoint in the main thread. 231 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1) 232 233 # The breakpoint list should show 1 breakpoints with 1 location. 234 self.expect("breakpoint list -f", "Breakpoint location shown correctly", 235 substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1]) 236 237 # Run the program. 238 self.runCmd("run", RUN_SUCCEEDED) 239 240 # The stop reason of the thread should be breakpoint. 241 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 242 substrs = ['stopped', 243 '* thread #1', 244 'stop reason = breakpoint']) 245 246 # Get the target process 247 target = self.dbg.GetSelectedTarget() 248 process = target.GetProcess() 249 250 # Get the number of threads 251 num_threads = process.GetNumThreads() 252 253 self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.') 254 255 # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change. 256 self.dbg.SetAsync(True) 257 self.runCmd("continue") 258 time.sleep(1) 259 260 # Go back to synchronous interactions 261 self.dbg.SetAsync(False) 262 263 # Stop the process 264 self.runCmd("process interrupt") 265 266 # The stop reason of the thread should be signal. 267 self.expect("process status", STOPPED_DUE_TO_SIGNAL, 268 substrs = ['stopped', 269 '* thread #1', 270 'stop reason = signal']) 271 272 # Get the inferior out of its loop 273 self.runCmd("expression g_test = 1") 274 275 # Run to completion 276 self.runCmd("continue") 277 278 def thread_states_test(self): 279 """Test thread states (comprehensive).""" 280 exe = os.path.join(os.getcwd(), "a.out") 281 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 282 283 # This should create a breakpoint in the main thread. 284 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_1, num_expected_locations=1) 285 lldbutil.run_break_set_by_file_and_line (self, "main.c", self.break_2, num_expected_locations=1) 286 287 # The breakpoint list should show 2 breakpoints with 1 location each. 288 self.expect("breakpoint list -f", "Breakpoint location shown correctly", 289 substrs = ["1: file = 'main.c', line = %d, locations = 1" % self.break_1, 290 "2: file = 'main.c', line = %d, locations = 1" % self.break_2]) 291 292 # Run the program. 293 self.runCmd("run", RUN_SUCCEEDED) 294 295 # The stop reason of the thread should be breakpoint. 296 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 297 substrs = ['stopped', 298 '* thread #1', 299 'stop reason = breakpoint']) 300 301 # Get the target process 302 target = self.dbg.GetSelectedTarget() 303 process = target.GetProcess() 304 305 # Get the number of threads 306 num_threads = process.GetNumThreads() 307 308 self.assertTrue(num_threads == 1, 'Number of expected threads and actual threads do not match.') 309 310 # Get the thread object 311 thread = process.GetThreadAtIndex(0) 312 313 # Make sure the thread is in the stopped state. 314 self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 1.") 315 self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 1.") 316 317 # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change. 318 self.dbg.SetAsync(True) 319 self.runCmd("continue") 320 time.sleep(1) 321 322 # Check the thread state. It should be running. 323 self.assertFalse(thread.IsStopped(), "Thread state is \'stopped\' when it should be running.") 324 self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' when it should be running.") 325 326 # Go back to synchronous interactions 327 self.dbg.SetAsync(False) 328 329 # Stop the process 330 self.runCmd("process interrupt") 331 332 # The stop reason of the thread should be signal. 333 self.expect("process status", STOPPED_DUE_TO_SIGNAL, 334 substrs = ['stopped', 335 '* thread #1', 336 'stop reason = signal']) 337 338 # Check the thread state 339 self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after process stop.") 340 self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after process stop.") 341 342 # Get the inferior out of its loop 343 self.runCmd("expression g_test = 1") 344 345 # Check the thread state 346 self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after expression evaluation.") 347 self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after expression evaluation.") 348 349 # The stop reason of the thread should be signal. 350 self.expect("process status", STOPPED_DUE_TO_SIGNAL, 351 substrs = ['stopped', 352 '* thread #1', 353 'stop reason = signal']) 354 355 # Run to breakpoint 2 356 self.runCmd("continue") 357 358 # The stop reason of the thread should be breakpoint. 359 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 360 substrs = ['stopped', 361 '* thread #1', 362 'stop reason = breakpoint']) 363 364 # Make sure both threads are stopped 365 self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' during breakpoint 2.") 366 self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' during breakpoint 2.") 367 368 # Run to completion 369 self.runCmd("continue") 370 371 # At this point, the inferior process should have exited. 372 self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED) 373 374 if __name__ == '__main__': 375 import atexit 376 lldb.SBDebugger.Initialize() 377 atexit.register(lambda: lldb.SBDebugger.Terminate()) 378 unittest2.main() 379