201 lines · python
1"""2Test the "process continue -b" option.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11 12class TestContinueToBkpts(TestBase):13 NO_DEBUG_INFO_TESTCASE = True14 15 @add_test_categories(["pyapi"])16 def test_continue_to_breakpoints(self):17 """Test that the continue to breakpoints feature works correctly."""18 self.build()19 self.do_test_continue_to_breakpoint()20 21 def setUp(self):22 # Call super's setUp().23 TestBase.setUp(self)24 self.main_source_spec = lldb.SBFileSpec("main.c")25 26 def continue_and_check(self, stop_list, bkpt_to_hit, loc_to_hit=0):27 """Build up a command that will run a continue -b commands using the breakpoints on stop_list, and28 ensure that we hit bkpt_to_hit.29 If loc_to_hit is not 0, also verify that we hit that location."""30 command = "process continue"31 for elem in stop_list:32 command += " -b {0}".format(elem)33 self.expect(command)34 self.assertStopReason(35 self.thread.stop_reason, lldb.eStopReasonBreakpoint, "Hit a breakpoint"36 )37 self.assertEqual(38 self.thread.GetStopReasonDataAtIndex(0),39 bkpt_to_hit,40 "Hit the right breakpoint",41 )42 if loc_to_hit != 0:43 self.assertEqual(44 self.thread.GetStopReasonDataAtIndex(1),45 loc_to_hit,46 "Hit the right location",47 )48 for bkpt_id in self.bkpt_list:49 bkpt = self.target.FindBreakpointByID(bkpt_id)50 self.assertTrue(bkpt.IsValid(), "Breakpoint id's round trip")51 if bkpt.MatchesName("disabled"):52 self.assertFalse(53 bkpt.IsEnabled(),54 "Disabled breakpoints stay disabled: {0}".format(bkpt.GetID()),55 )56 else:57 self.assertTrue(58 bkpt.IsEnabled(),59 "Enabled breakpoints stay enabled: {0}".format(bkpt.GetID()),60 )61 # Also do our multiple location one:62 bkpt = self.target.FindBreakpointByID(self.multiple_loc_id)63 self.assertTrue(bkpt.IsValid(), "Breakpoint with locations round trip")64 for i in range(1, 3):65 loc = bkpt.FindLocationByID(i)66 self.assertTrue(loc.IsValid(), "Locations round trip")67 if i == 2:68 self.assertTrue(69 loc.IsEnabled(), "Locations that were enabled stay enabled"70 )71 else:72 self.assertFalse(73 loc.IsEnabled(), "Locations that were disabled stay disabled"74 )75 76 def do_test_continue_to_breakpoint(self):77 """Test the continue to breakpoint feature."""78 (self.target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(79 self, "Stop here to get started", self.main_source_spec80 )81 82 # Now set up all our breakpoints:83 bkpt_pattern = "This is the {0} stop"84 bkpt_elements = [85 "zeroth",86 "first",87 "second",88 "third",89 "fourth",90 "fifth",91 "sixth",92 "seventh",93 "eighth",94 "nineth",95 ]96 disabled_bkpts = ["first", "eigth"]97 bkpts_for_MyBKPT = ["first", "sixth", "nineth"]98 self.bkpt_list = []99 for elem in bkpt_elements:100 bkpt = self.target.BreakpointCreateBySourceRegex(101 bkpt_pattern.format(elem), self.main_source_spec102 )103 self.assertGreater(bkpt.GetNumLocations(), 0, "Found a bkpt match")104 self.bkpt_list.append(bkpt.GetID())105 bkpt.AddName(elem)106 if elem in disabled_bkpts:107 bkpt.AddName("disabled")108 bkpt.SetEnabled(False)109 if elem in bkpts_for_MyBKPT:110 bkpt.AddName("MyBKPT")111 # Also make one that has several locations, so we can test locations:112 mult_bkpt = self.target.BreakpointCreateBySourceRegex(113 bkpt_pattern.format("(seventh|eighth|nineth)"), self.main_source_spec114 )115 self.assertEqual(mult_bkpt.GetNumLocations(), 3, "Got three matches")116 mult_bkpt.AddName("Locations")117 # Disable all of these:118 for i in range(1, 4):119 loc = mult_bkpt.FindLocationByID(i)120 self.assertTrue(loc.IsValid(), "Location {0} is valid".format(i))121 loc.SetEnabled(False)122 self.assertFalse(loc.IsEnabled(), "Loc {0} wasn't disabled".format(i))123 self.multiple_loc_id = mult_bkpt.GetID()124 125 # First test out various error conditions126 127 # All locations of the multiple_loc_id are disabled, so running to this should be an error:128 self.expect(129 "process continue -b {0}".format(self.multiple_loc_id),130 error=True,131 msg="Running to a disabled breakpoint by number",132 )133 134 # Now re-enable the middle one so we can run to it:135 loc = mult_bkpt.FindLocationByID(2)136 loc.SetEnabled(True)137 138 self.expect(139 "process continue -b {0}".format(self.bkpt_list[1]),140 error=True,141 msg="Running to a disabled breakpoint by number",142 )143 self.expect(144 "process continue -b {0}.1".format(self.bkpt_list[1]),145 error=True,146 msg="Running to a location of a disabled breakpoint",147 )148 self.expect(149 "process continue -b disabled",150 error=True,151 msg="Running to a disabled set of breakpoints",152 )153 self.expect(154 "process continue -b {0}.{1}".format(self.multiple_loc_id, 1),155 error=True,156 msg="Running to a disabled breakpoint location",157 )158 self.expect(159 "process continue -b {0}".format("THERE_ARE_NO_BREAKPOINTS_BY_THIS_NAME"),160 error=True,161 msg="Running to no such name",162 )163 self.expect(164 "process continue -b {0}".format(1000),165 error=True,166 msg="Running to no such breakpoint",167 )168 self.expect(169 "process continue -b {0}.{1}".format(self.multiple_loc_id, 1000),170 error=True,171 msg="Running to no such location",172 )173 174 # Now move forward, this time with breakpoint numbers. First time we don't skip other bkpts.175 bkpt = self.bkpt_list[0]176 self.continue_and_check([str(bkpt)], bkpt)177 178 # Now skip to the third stop, do it by name and supply one of the later breakpoints as well:179 # This continue has to muck with the sync mode of the debugger, so let's make sure we180 # put it back. First try if it was in sync mode:181 orig_async = self.dbg.GetAsync()182 self.dbg.SetAsync(True)183 self.continue_and_check([bkpt_elements[2], bkpt_elements[7]], self.bkpt_list[2])184 after_value = self.dbg.GetAsync()185 self.dbg.SetAsync(orig_async)186 self.assertTrue(after_value, "Preserve async as True if it started that way")187 188 # Now try a name that has several breakpoints.189 # This time I'm also going to check that we put the debugger async mode back if190 # if was False to begin with:191 self.dbg.SetAsync(False)192 self.continue_and_check(["MyBKPT"], self.bkpt_list[6])193 after_value = self.dbg.GetAsync()194 self.dbg.SetAsync(orig_async)195 self.assertFalse(after_value, "Preserve async as False if it started that way")196 197 # Now let's run to a particular location. Also specify a breakpoint we've already hit:198 self.continue_and_check(199 [self.bkpt_list[0], self.multiple_loc_id], self.multiple_loc_id, 2200 )201