360 lines · python
1"""2Test breakpoint commands for a breakpoint ID with multiple locations.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11 12class BreakpointLocationsTestCase(TestBase):13 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")14 def test_enable(self):15 """Test breakpoint enable/disable for a breakpoint ID with multiple locations."""16 self.build()17 self.breakpoint_locations_test()18 19 def test_shadowed_cond_options(self):20 """Test that options set on the breakpoint and location behave correctly."""21 self.build()22 self.shadowed_bkpt_cond_test()23 24 def test_shadowed_command_options(self):25 """Test that options set on the breakpoint and location behave correctly."""26 self.build()27 self.shadowed_bkpt_command_test()28 29 def setUp(self):30 # Call super's setUp().31 TestBase.setUp(self)32 # Find the line number to break inside main().33 self.line = line_number("main.c", "// Set break point at this line.")34 35 def set_breakpoint(self):36 exe = self.getBuildArtifact("a.out")37 target = self.dbg.CreateTarget(exe)38 self.assertTrue(target, "Target %s is not valid" % (exe))39 40 # This should create a breakpoint with 3 locations.41 42 bkpt = target.BreakpointCreateByLocation("main.c", self.line)43 44 # The breakpoint list should show 3 locations.45 self.assertEqual(bkpt.GetNumLocations(), 3, "Wrong number of locations")46 47 self.expect(48 "breakpoint list -f",49 "Breakpoint locations shown correctly",50 ordered=False,51 substrs=[52 f"1: file = 'main.c', line = {self.line}, exact_match = 0, locations = 3"53 ],54 patterns=[55 "where = a.out`func_inlined .+?unresolved, hit count = 0",56 r"where = a.out`main .+?\[inlined\].+?unresolved, hit count = 0",57 ],58 )59 60 return bkpt61 62 def shadowed_bkpt_cond_test(self):63 """Test that options set on the breakpoint and location behave correctly."""64 # Breakpoint option propagation from bkpt to loc used to be done the first time65 # a breakpoint location option was specifically set. After that the other options66 # on that location would stop tracking the breakpoint. That got fixed, and this test67 # makes sure only the option touched is affected.68 69 bkpt = self.set_breakpoint()70 bkpt_cond = "1 == 0"71 bkpt.SetCondition(bkpt_cond)72 self.assertEqual(bkpt.GetCondition(), bkpt_cond, "Successfully set condition")73 self.assertEqual(74 bkpt.location[0].GetCondition(),75 bkpt.GetCondition(),76 "Conditions are the same",77 )78 79 # Now set a condition on the locations, make sure that this doesn't effect the bkpt:80 bkpt_loc_1_cond = "1 == 1"81 bkpt.location[0].SetCondition(bkpt_loc_1_cond)82 self.assertEqual(83 bkpt.location[0].GetCondition(),84 bkpt_loc_1_cond,85 "Successfully changed location condition",86 )87 self.assertNotEqual(88 bkpt.GetCondition(),89 bkpt_loc_1_cond,90 "Changed location changed Breakpoint condition",91 )92 self.assertEqual(93 bkpt.location[1].GetCondition(),94 bkpt_cond,95 "Changed another location's condition",96 )97 98 # Now make sure that setting one options doesn't fix the value of another:99 bkpt.SetIgnoreCount(10)100 self.assertEqual(bkpt.GetIgnoreCount(), 10, "Set the ignore count successfully")101 self.assertEqual(102 bkpt.location[0].GetIgnoreCount(),103 10,104 "Location doesn't track top-level bkpt.",105 )106 107 # Now make sure resetting the condition to "" resets the tracking:108 bkpt.location[0].SetCondition("")109 bkpt_new_cond = "1 == 3"110 bkpt.SetCondition(bkpt_new_cond)111 self.assertEqual(112 bkpt.location[0].GetCondition(),113 bkpt_new_cond,114 "Didn't go back to tracking condition",115 )116 117 # Test that set/get accessor methods on BreakpointLocation behave correctly.118 bkpt_loc = bkpt.GetLocationAtIndex(0)119 120 value = "MyQueue"121 bkpt_loc.SetQueueName(value)122 self.assertEqual(123 bkpt_loc.GetQueueName(), value, "Successfully set/get bp location QueueName"124 )125 126 value = 5127 bkpt_loc.SetThreadID(value)128 self.assertEqual(129 bkpt_loc.GetThreadID(), value, "Successfully set/get bp location ThreadID"130 )131 132 value = "1 == 0"133 bkpt_loc.SetCondition(value)134 self.assertEqual(135 bkpt_loc.GetCondition(), value, "Successfully set/get bp location Condition"136 )137 138 value = 6139 bkpt_loc.SetThreadIndex(value)140 self.assertEqual(141 bkpt_loc.GetThreadIndex(),142 value,143 "Successfully set/get bp location ThreadIndex",144 )145 146 value = "MyThread"147 bkpt_loc.SetThreadName(value)148 self.assertEqual(149 bkpt_loc.GetThreadName(),150 value,151 "Successfully set/get bp location ThreadName",152 )153 154 value = 5155 bkpt_loc.SetIgnoreCount(value)156 self.assertEqual(157 bkpt_loc.GetIgnoreCount(),158 value,159 "Successfully set/get bp location IgnoreCount",160 )161 162 for value in [True, False]:163 bkpt_loc.SetAutoContinue(value)164 self.assertEqual(165 bkpt_loc.GetAutoContinue(),166 value,167 "Successfully set/get bp location AutoContinue",168 )169 170 for value in [True, False]:171 bkpt_loc.SetEnabled(value)172 self.assertEqual(173 bkpt_loc.IsEnabled(),174 value,175 "Successfully set/get bp location SetEnabled",176 )177 178 # test set/get CommandLineCommands179 set_cmds = lldb.SBStringList()180 set_cmds.AppendString("frame var")181 set_cmds.AppendString("bt")182 bkpt_loc.SetCommandLineCommands(set_cmds)183 184 get_cmds = lldb.SBStringList()185 bkpt_loc.GetCommandLineCommands(get_cmds)186 self.assertEqual(187 set_cmds.GetSize(), get_cmds.GetSize(), "Size of command line commands"188 )189 for idx, _ in enumerate(set_cmds):190 self.assertEqual(191 set_cmds.GetStringAtIndex(idx),192 get_cmds.GetStringAtIndex(idx),193 "Command %d" % (idx),194 )195 196 def shadowed_bkpt_command_test(self):197 """Test that options set on the breakpoint and location behave correctly."""198 # Breakpoint option propagation from bkpt to loc used to be done the first time199 # a breakpoint location option was specifically set. After that the other options200 # on that location would stop tracking the breakpoint. That got fixed, and this test201 # makes sure only the option touched is affected.202 203 bkpt = self.set_breakpoint()204 commands = ["AAAAAA", "BBBBBB", "CCCCCC"]205 str_list = lldb.SBStringList()206 str_list.AppendList(commands, len(commands))207 208 bkpt.SetCommandLineCommands(str_list)209 cmd_list = lldb.SBStringList()210 bkpt.GetCommandLineCommands(cmd_list)211 list_size = str_list.GetSize()212 self.assertEqual(213 cmd_list.GetSize(), list_size, "Added the right number of commands"214 )215 for i in range(0, list_size):216 self.assertEqual(217 str_list.GetStringAtIndex(i),218 cmd_list.GetStringAtIndex(i),219 "Mismatched commands.",220 )221 222 commands = ["DDDDDD", "EEEEEE", "FFFFFF", "GGGGGG"]223 loc_list = lldb.SBStringList()224 loc_list.AppendList(commands, len(commands))225 bkpt.location[1].SetCommandLineCommands(loc_list)226 loc_cmd_list = lldb.SBStringList()227 bkpt.location[1].GetCommandLineCommands(loc_cmd_list)228 229 loc_list_size = loc_list.GetSize()230 231 # Check that the location has the right commands:232 self.assertEqual(233 loc_cmd_list.GetSize(),234 loc_list_size,235 "Added the right number of commands to location",236 )237 for i in range(0, loc_list_size):238 self.assertEqual(239 loc_list.GetStringAtIndex(i),240 loc_cmd_list.GetStringAtIndex(i),241 "Mismatched commands.",242 )243 244 # Check that we didn't mess up the breakpoint level commands:245 self.assertEqual(246 cmd_list.GetSize(), list_size, "Added the right number of commands"247 )248 for i in range(0, list_size):249 self.assertEqual(250 str_list.GetStringAtIndex(i),251 cmd_list.GetStringAtIndex(i),252 "Mismatched commands.",253 )254 255 # And check we didn't mess up another location:256 untouched_loc_cmds = lldb.SBStringList()257 bkpt.location[0].GetCommandLineCommands(untouched_loc_cmds)258 self.assertEqual(untouched_loc_cmds.GetSize(), 0, "Changed the wrong location")259 260 def breakpoint_locations_test(self):261 """Test breakpoint enable/disable for a breakpoint ID with multiple locations."""262 self.set_breakpoint()263 264 # The 'breakpoint disable 3.*' command should fail gracefully.265 self.expect(266 "breakpoint disable 3.*",267 "Disabling an invalid breakpoint should fail gracefully",268 error=True,269 startstr="error: '3' is not a valid breakpoint ID.",270 )271 272 # The 'breakpoint disable 1.*' command should disable all 3 locations.273 self.expect(274 "breakpoint disable 1.*",275 "All 3 breakpoint locatons disabled correctly",276 startstr="3 breakpoints disabled.",277 )278 279 # Run the program.280 self.runCmd("run", RUN_SUCCEEDED)281 282 # We should not stopped on any breakpoint at all.283 self.expect(284 "process status",285 "No stopping on any disabled breakpoint",286 patterns=["^Process [0-9]+ exited with status = 0"],287 )288 289 # The 'breakpoint enable 1.*' command should enable all 3 breakpoints.290 self.expect(291 "breakpoint enable 1.*",292 "All 3 breakpoint locatons enabled correctly",293 startstr="3 breakpoints enabled.",294 )295 296 # The 'breakpoint enable 1.' command should not crash.297 self.expect(298 "breakpoint enable 1.",299 startstr="0 breakpoints enabled.",300 )301 302 # The 'breakpoint disable 1.1' command should disable 1 location.303 self.expect(304 "breakpoint disable 1.1",305 "1 breakpoint locatons disabled correctly",306 startstr="1 breakpoints disabled.",307 )308 309 # Run the program again. We should stop on the two breakpoint310 # locations.311 self.runCmd("run", RUN_SUCCEEDED)312 313 # Stopped once.314 self.expect(315 "thread backtrace",316 STOPPED_DUE_TO_BREAKPOINT,317 substrs=["stop reason = breakpoint 1."],318 )319 320 # Continue the program, there should be another stop.321 self.runCmd("process continue")322 323 # Stopped again.324 self.expect(325 "thread backtrace",326 STOPPED_DUE_TO_BREAKPOINT,327 substrs=["stop reason = breakpoint 1."],328 )329 330 # At this point, 1.1 has a hit count of 0 and the other a hit count of331 # 1".332 lldbutil.check_breakpoint(333 self,334 bpno=1,335 expected_locations=3,336 expected_resolved_count=2,337 expected_hit_count=2,338 )339 lldbutil.check_breakpoint(340 self,341 bpno=1,342 location_id=1,343 expected_location_resolved=False,344 expected_location_hit_count=0,345 )346 lldbutil.check_breakpoint(347 self,348 bpno=1,349 location_id=2,350 expected_location_resolved=True,351 expected_location_hit_count=1,352 )353 lldbutil.check_breakpoint(354 self,355 bpno=1,356 location_id=3,357 expected_location_resolved=True,358 expected_location_hit_count=1,359 )360