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