1""" 2Test breakpoint commands for a breakpoint ID with multiple locations. 3""" 4 5 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 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 substrs=[ 51 "1: file = 'main.c', line = %d, exact_match = 0, locations = 3" 52 % self.line 53 ], 54 patterns=[ 55 "where = a.out`func_inlined .+unresolved, hit count = 0", 56 "where = a.out`main .+\[inlined\].+unresolved, hit count = 0", 57 ], 58 ) 59 60 return bkpt 61 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 time 65 # a breakpoint location option was specifically set. After that the other options 66 # on that location would stop tracking the breakpoint. That got fixed, and this test 67 # 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 = 5 127 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 = 6 139 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 = 5 155 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 CommandLineCommands 179 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 time 199 # a breakpoint location option was specifically set. After that the other options 200 # on that location would stop tracking the breakpoint. That got fixed, and this test 201 # 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 breakpoint 310 # 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 of 331 # 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