1""" 2Test number of threads. 3""" 4 5 6 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10import lldbsuite.test.lldbutil as lldbutil 11 12 13class ThreadExitTestCase(TestBase): 14 15 def setUp(self): 16 # Call super's setUp(). 17 TestBase.setUp(self) 18 # Find the line numbers for our breakpoints. 19 self.break_1 = line_number('main.cpp', '// Set first breakpoint here') 20 self.break_2 = line_number('main.cpp', '// Set second breakpoint here') 21 self.break_3 = line_number('main.cpp', '// Set third breakpoint here') 22 self.break_4 = line_number('main.cpp', '// Set fourth breakpoint here') 23 24 @skipIfWindows # This is flakey on Windows: llvm.org/pr38373 25 def test(self): 26 """Test thread exit handling.""" 27 self.build() 28 exe = self.getBuildArtifact("a.out") 29 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 30 31 # This should create a breakpoint with 1 location. 32 bp1_id = lldbutil.run_break_set_by_file_and_line( 33 self, "main.cpp", self.break_1, num_expected_locations=1) 34 bp2_id = lldbutil.run_break_set_by_file_and_line( 35 self, "main.cpp", self.break_2, num_expected_locations=1) 36 bp3_id = lldbutil.run_break_set_by_file_and_line( 37 self, "main.cpp", self.break_3, num_expected_locations=1) 38 bp4_id = lldbutil.run_break_set_by_file_and_line( 39 self, "main.cpp", self.break_4, num_expected_locations=1) 40 41 # The breakpoint list should show 1 locations. 42 self.expect( 43 "breakpoint list -f", 44 "Breakpoint location shown correctly", 45 substrs=[ 46 "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % 47 self.break_1, 48 "2: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % 49 self.break_2, 50 "3: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % 51 self.break_3, 52 "4: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % 53 self.break_4]) 54 55 # Run the program. 56 self.runCmd("run", RUN_SUCCEEDED) 57 # Get the target process 58 target = self.dbg.GetSelectedTarget() 59 process = target.GetProcess() 60 61 stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( 62 process, bp1_id) 63 self.assertIsNotNone(stopped_thread, 64 "Process is not stopped at breakpoint 1") 65 66 # Get the number of threads 67 num_threads = process.GetNumThreads() 68 self.assertGreaterEqual( 69 num_threads, 70 2, 71 'Number of expected threads and actual threads do not match at breakpoint 1.') 72 73 # Run to the second breakpoint 74 self.runCmd("continue") 75 stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( 76 process, bp2_id) 77 self.assertIsNotNone(stopped_thread, 78 "Process is not stopped at breakpoint 2") 79 80 # Update the number of threads 81 new_num_threads = process.GetNumThreads() 82 self.assertEqual( 83 new_num_threads, 84 num_threads + 1, 85 'Number of expected threads did not increase by 1 at bp 2.') 86 87 # Run to the third breakpoint 88 self.runCmd("continue") 89 stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( 90 process, bp3_id) 91 self.assertIsNotNone(stopped_thread, 92 "Process is not stopped at breakpoint 3") 93 94 # Update the number of threads 95 new_num_threads = process.GetNumThreads() 96 self.assertEqual( 97 new_num_threads, 98 num_threads, 99 'Number of expected threads is not equal to original number of threads at bp 3.') 100 101 # Run to the fourth breakpoint 102 self.runCmd("continue") 103 stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( 104 process, bp4_id) 105 self.assertIsNotNone(stopped_thread, 106 "Process is not stopped at breakpoint 4") 107 108 # Update the number of threads 109 new_num_threads = process.GetNumThreads() 110 self.assertEqual( 111 new_num_threads, 112 num_threads - 1, 113 'Number of expected threads did not decrease by 1 at bp 4.') 114 115 # Run to completion 116 self.runCmd("continue") 117 118 # At this point, the inferior process should have exited. 119 self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED) 120