152 lines · python
1"""2Test number of threads.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11 12class ExitDuringStepTestCase(TestBase):13 @skipIfWindows # This is flakey on Windows: llvm.org/pr3837314 def test(self):15 """Test thread exit during step handling."""16 self.build()17 self.exit_during_step_base(18 "thread step-inst -m all-threads", "stop reason = instruction step", True19 )20 21 @skipIfWindows # This is flakey on Windows: llvm.org/pr3837322 def test_step_over(self):23 """Test thread exit during step-over handling."""24 self.build()25 self.exit_during_step_base(26 "thread step-over -m all-threads", "stop reason = step over", False27 )28 29 @skipIfWindows # This is flakey on Windows: llvm.org/pr3837330 def test_step_in(self):31 """Test thread exit during step-in handling."""32 self.build()33 self.exit_during_step_base(34 "thread step-in -m all-threads", "stop reason = step in", False35 )36 37 def setUp(self):38 # Call super's setUp().39 TestBase.setUp(self)40 # Find the line numbers to break and continue.41 self.breakpoint = line_number("main.cpp", "// Set breakpoint here")42 self.continuepoint = line_number("main.cpp", "// Continue from here")43 44 def exit_during_step_base(self, step_cmd, step_stop_reason, by_instruction):45 """Test thread exit during step handling."""46 exe = self.getBuildArtifact("a.out")47 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)48 49 # This should create a breakpoint in the main thread.50 self.bp_num = lldbutil.run_break_set_by_file_and_line(51 self, "main.cpp", self.breakpoint, num_expected_locations=152 )53 54 # The breakpoint list should show 1 location.55 self.expect(56 "breakpoint list -f",57 "Breakpoint location shown correctly",58 substrs=[59 "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1"60 % self.breakpoint61 ],62 )63 64 # Run the program.65 self.runCmd("run", RUN_SUCCEEDED)66 67 # The stop reason of the thread should be breakpoint.68 self.expect(69 "thread list",70 STOPPED_DUE_TO_BREAKPOINT,71 substrs=["stopped", "stop reason = breakpoint"],72 )73 74 # Get the target process75 target = self.dbg.GetSelectedTarget()76 process = target.GetProcess()77 78 num_threads = process.GetNumThreads()79 # Make sure we see all three threads80 self.assertGreaterEqual(81 num_threads,82 3,83 "Number of expected threads and actual threads do not match.",84 )85 86 stepping_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id(87 process, self.bp_num88 )89 self.assertIsNotNone(90 stepping_thread, "Could not find a thread stopped at the breakpoint"91 )92 93 current_line = self.breakpoint94 stepping_frame = stepping_thread.GetFrameAtIndex(0)95 self.assertEqual(96 current_line,97 stepping_frame.GetLineEntry().GetLine(),98 "Starting line for stepping doesn't match breakpoint line.",99 )100 101 # Keep stepping until we've reached our designated continue point102 while current_line != self.continuepoint:103 # Since we're using the command interpreter to issue the thread command104 # (on the selected thread) we need to ensure the selected thread is the105 # stepping thread.106 if stepping_thread != process.GetSelectedThread():107 process.SetSelectedThread(stepping_thread)108 109 self.runCmd(step_cmd)110 111 frame = stepping_thread.GetFrameAtIndex(0)112 113 current_line = frame.GetLineEntry().GetLine()114 115 if by_instruction and current_line == 0:116 continue117 118 self.assertGreaterEqual(119 current_line,120 self.breakpoint,121 "Stepped to unexpected line, " + str(current_line),122 )123 self.assertLessEqual(124 current_line,125 self.continuepoint,126 "Stepped to unexpected line, " + str(current_line),127 )128 129 self.runCmd("thread list")130 131 # Update the number of threads132 new_num_threads = process.GetNumThreads()133 134 # Check to see that we reduced the number of threads as expected135 self.assertEqual(136 new_num_threads,137 num_threads - 1,138 "Number of threads did not reduce by 1 after thread exit.",139 )140 141 self.expect(142 "thread list",143 "Process state is stopped due to step",144 substrs=["stopped", step_stop_reason],145 )146 147 # Run to completion148 self.runCmd("continue")149 150 # At this point, the inferior process should have exited.151 self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED)152