9 from lldbsuite.test.decorators import *
10 from lldbsuite.test.lldbtest import *
11 from lldbsuite.test import lldbutil
14 class BreakpointNames(TestBase):
16 mydir = TestBase.compute_mydir(__file__)
17 NO_DEBUG_INFO_TESTCASE = True
19 @add_test_categories(['pyapi'])
20 def test_setting_names(self):
21 """Use Python APIs to test that we can set breakpoint names."""
26 def test_illegal_names(self):
27 """Use Python APIs to test that we don't allow illegal names."""
30 self.do_check_illegal_names()
32 def test_using_names(self):
33 """Use Python APIs to test that operations on names works correctly."""
36 self.do_check_using_names()
38 def test_configuring_names(self):
39 """Use Python APIs to test that configuring options on breakpoint names works correctly."""
41 self.make_a_dummy_name()
43 self.do_check_configuring_names()
45 def test_configuring_permissions_sb(self):
46 """Use Python APIs to test that configuring permissions on names works correctly."""
49 self.do_check_configuring_permissions_sb()
51 def test_configuring_permissions_cli(self):
52 """Use Python APIs to test that configuring permissions on names works correctly."""
55 self.do_check_configuring_permissions_cli()
57 def setup_target(self):
58 exe = self.getBuildArtifact("a.out")
60 # Create a targets we are making breakpoint in and copying to:
61 self.target = self.dbg.CreateTarget(exe)
62 self.assertTrue(self.target, VALID_TARGET)
63 self.main_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "main.c"))
65 def check_name_in_target(self, bkpt_name):
66 name_list = lldb.SBStringList()
67 self.target.GetBreakpointNames(name_list)
69 for name in name_list:
73 self.assertTrue(found_it, "Didn't find the name %s in the target's name list:"%(bkpt_name))
76 # Call super's setUp().
79 # These are the settings we're going to be putting into names & breakpoints:
80 self.bp_name_string = "ABreakpoint"
81 self.is_one_shot = True
82 self.ignore_count = 1000
83 self.condition = "1 == 2"
84 self.auto_continue = True
87 self.thread_name = "Fooey"
88 self.queue_name = "Blooey"
89 self.cmd_list = lldb.SBStringList()
90 self.cmd_list.AppendString("frame var")
91 self.cmd_list.AppendString("bt")
92 self.help_string = "I do something interesting"
95 def do_check_names(self):
96 """Use Python APIs to check that we can set & retrieve breakpoint names"""
97 bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
98 bkpt_name = "ABreakpoint"
99 other_bkpt_name = "_AnotherBreakpoint"
101 # Add a name and make sure we match it:
102 success = bkpt.AddName(bkpt_name)
103 self.assertTrue(success, "We couldn't add a legal name to a breakpoint.")
105 matches = bkpt.MatchesName(bkpt_name)
106 self.assertTrue(matches, "We didn't match the name we just set")
108 # Make sure we don't match irrelevant names:
109 matches = bkpt.MatchesName("NotABreakpoint")
110 self.assertTrue(not matches, "We matched a name we didn't set.")
112 # Make sure the name is also in the target:
113 self.check_name_in_target(bkpt_name)
115 # Add another name, make sure that works too:
116 bkpt.AddName(other_bkpt_name)
118 matches = bkpt.MatchesName(bkpt_name)
119 self.assertTrue(matches, "Adding a name means we didn't match the name we just set")
120 self.check_name_in_target(other_bkpt_name)
122 # Remove the name and make sure we no longer match it:
123 bkpt.RemoveName(bkpt_name)
124 matches = bkpt.MatchesName(bkpt_name)
125 self.assertTrue(not matches,"We still match a name after removing it.")
127 # Make sure the name list has the remaining name:
128 name_list = lldb.SBStringList()
129 bkpt.GetNames(name_list)
130 num_names = name_list.GetSize()
131 self.assertTrue(num_names == 1, "Name list has %d items, expected 1."%(num_names))
133 name = name_list.GetStringAtIndex(0)
134 self.assertTrue(name == other_bkpt_name, "Remaining name was: %s expected %s."%(name, other_bkpt_name))
136 def do_check_illegal_names(self):
137 """Use Python APIs to check that we reject illegal names."""
138 bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
139 bad_names = ["-CantStartWithADash",
140 "1CantStartWithANumber",
141 "^CantStartWithNonAlpha",
144 for bad_name in bad_names:
145 success = bkpt.AddName(bad_name)
146 self.assertTrue(not success,"We allowed an illegal name: %s"%(bad_name))
147 bp_name = lldb.SBBreakpointName(self.target, bad_name)
148 self.assertFalse(bp_name.IsValid(), "We made a breakpoint name with an illegal name: %s"%(bad_name));
150 retval =lldb.SBCommandReturnObject()
151 self.dbg.GetCommandInterpreter().HandleCommand("break set -n whatever -N '%s'"%(bad_name), retval)
152 self.assertTrue(not retval.Succeeded(), "break set succeeded with: illegal name: %s"%(bad_name))
154 def do_check_using_names(self):
155 """Use Python APIs to check names work in place of breakpoint ID's."""
157 # Create a dummy breakpoint to use up ID 1
158 _ = self.target.BreakpointCreateByLocation(self.main_file_spec, 30)
160 # Create a breakpiont to test with
161 bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
162 bkpt_name = "ABreakpoint"
163 bkpt_id = bkpt.GetID()
164 other_bkpt_name= "_AnotherBreakpoint"
166 # Add a name and make sure we match it:
167 success = bkpt.AddName(bkpt_name)
168 self.assertTrue(success, "We couldn't add a legal name to a breakpoint.")
170 bkpts = lldb.SBBreakpointList(self.target)
171 self.target.FindBreakpointsByName(bkpt_name, bkpts)
173 self.assertTrue(bkpts.GetSize() == 1, "One breakpoint matched.")
174 found_bkpt = bkpts.GetBreakpointAtIndex(0)
175 self.assertTrue(bkpt.GetID() == found_bkpt.GetID(),"The right breakpoint.")
176 self.assertTrue(bkpt.GetID() == bkpt_id,"With the same ID as before.")
178 retval = lldb.SBCommandReturnObject()
179 self.dbg.GetCommandInterpreter().HandleCommand("break disable %s"%(bkpt_name), retval)
180 self.assertTrue(retval.Succeeded(), "break disable failed with: %s."%(retval.GetError()))
181 self.assertTrue(not bkpt.IsEnabled(), "We didn't disable the breakpoint.")
183 # Also make sure we don't apply commands to non-matching names:
184 self.dbg.GetCommandInterpreter().HandleCommand("break modify --one-shot 1 %s"%(other_bkpt_name), retval)
185 self.assertTrue(retval.Succeeded(), "break modify failed with: %s."%(retval.GetError()))
186 self.assertTrue(not bkpt.IsOneShot(), "We applied one-shot to the wrong breakpoint.")
188 def check_option_values(self, bp_object):
189 self.assertEqual(bp_object.IsOneShot(), self.is_one_shot, "IsOneShot")
190 self.assertEqual(bp_object.GetIgnoreCount(), self.ignore_count, "IgnoreCount")
191 self.assertEqual(bp_object.GetCondition(), self.condition, "Condition")
192 self.assertEqual(bp_object.GetAutoContinue(), self.auto_continue, "AutoContinue")
193 self.assertEqual(bp_object.GetThreadID(), self.tid, "Thread ID")
194 self.assertEqual(bp_object.GetThreadIndex(), self.tidx, "Thread Index")
195 self.assertEqual(bp_object.GetThreadName(), self.thread_name, "Thread Name")
196 self.assertEqual(bp_object.GetQueueName(), self.queue_name, "Queue Name")
197 set_cmds = lldb.SBStringList()
198 bp_object.GetCommandLineCommands(set_cmds)
199 self.assertEqual(set_cmds.GetSize(), self.cmd_list.GetSize(), "Size of command line commands")
200 for idx in range(0, set_cmds.GetSize()):
201 self.assertEqual(self.cmd_list.GetStringAtIndex(idx), set_cmds.GetStringAtIndex(idx), "Command %d"%(idx))
203 def make_a_dummy_name(self):
204 "This makes a breakpoint name in the dummy target to make sure it gets copied over"
206 dummy_target = self.dbg.GetDummyTarget()
207 self.assertTrue(dummy_target.IsValid(), "Dummy target was not valid.")
210 self.dbg.GetDummyTarget().DeleteBreakpointName(self.bp_name_string)
212 # Execute the cleanup function during test case tear down.
213 self.addTearDownHook(cleanup)
215 # Now find it in the dummy target, and make sure these settings took:
216 bp_name = lldb.SBBreakpointName(dummy_target, self.bp_name_string)
217 # Make sure the name is right:
218 self.assertTrue (bp_name.GetName() == self.bp_name_string, "Wrong bp_name: %s"%(bp_name.GetName()))
219 bp_name.SetOneShot(self.is_one_shot)
220 bp_name.SetIgnoreCount(self.ignore_count)
221 bp_name.SetCondition(self.condition)
222 bp_name.SetAutoContinue(self.auto_continue)
223 bp_name.SetThreadID(self.tid)
224 bp_name.SetThreadIndex(self.tidx)
225 bp_name.SetThreadName(self.thread_name)
226 bp_name.SetQueueName(self.queue_name)
227 bp_name.SetCommandLineCommands(self.cmd_list)
229 # Now look it up again, and make sure it got set correctly.
230 bp_name = lldb.SBBreakpointName(dummy_target, self.bp_name_string)
231 self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name.")
232 self.check_option_values(bp_name)
234 def do_check_configuring_names(self):
235 """Use Python APIs to check that configuring breakpoint names works correctly."""
236 other_bp_name_string = "AnotherBreakpointName"
237 cl_bp_name_string = "CLBreakpointName"
239 # Now find the version copied in from the dummy target, and make sure these settings took:
240 bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
241 self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name.")
242 self.check_option_values(bp_name)
244 # Now add this name to a breakpoint, and make sure it gets configured properly
245 bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
246 success = bkpt.AddName(self.bp_name_string)
247 self.assertTrue(success, "Couldn't add this name to the breakpoint")
248 self.check_option_values(bkpt)
250 # Now make a name from this breakpoint, and make sure the new name is properly configured:
251 new_name = lldb.SBBreakpointName(bkpt, other_bp_name_string)
252 self.assertTrue(new_name.IsValid(), "Couldn't make a valid bp_name from a breakpoint.")
253 self.check_option_values(bkpt)
255 # Now change the name's option and make sure it gets propagated to
257 new_auto_continue = not self.auto_continue
258 bp_name.SetAutoContinue(new_auto_continue)
259 self.assertEqual(bp_name.GetAutoContinue(), new_auto_continue, "Couldn't change auto-continue on the name")
260 self.assertEqual(bkpt.GetAutoContinue(), new_auto_continue, "Option didn't propagate to the breakpoint.")
262 # Now make this same breakpoint name - but from the command line
263 cmd_str = "breakpoint name configure %s -o %d -i %d -c '%s' -G %d -t %d -x %d -T '%s' -q '%s' -H '%s'"%(cl_bp_name_string,
273 for cmd in self.cmd_list:
274 cmd_str += " -C '%s'"%(cmd)
276 self.runCmd(cmd_str, check=True)
277 # Now look up this name again and check its options:
278 cl_name = lldb.SBBreakpointName(self.target, cl_bp_name_string)
279 self.check_option_values(cl_name)
280 # Also check the help string:
281 self.assertEqual(self.help_string, cl_name.GetHelpString(), "Help string didn't match")
282 # Change the name and make sure that works:
283 new_help = "I do something even more interesting"
284 cl_name.SetHelpString(new_help)
285 self.assertEqual(new_help, cl_name.GetHelpString(), "SetHelpString didn't")
287 # We should have three names now, make sure the target can list them:
288 name_list = lldb.SBStringList()
289 self.target.GetBreakpointNames(name_list)
290 for name_string in [self.bp_name_string, other_bp_name_string, cl_bp_name_string]:
291 self.assertTrue(name_string in name_list, "Didn't find %s in names"%(name_string))
293 # Delete the name from the current target. Make sure that works and deletes the
294 # name from the breakpoint as well:
295 self.target.DeleteBreakpointName(self.bp_name_string)
297 self.target.GetBreakpointNames(name_list)
298 self.assertTrue(self.bp_name_string not in name_list, "Didn't delete %s from a real target"%(self.bp_name_string))
299 # Also make sure the name got removed from breakpoints holding it:
300 self.assertFalse(bkpt.MatchesName(self.bp_name_string), "Didn't remove the name from the breakpoint.")
302 # Test that deleting the name we injected into the dummy target works (there's also a
303 # cleanup that will do this, but that won't test the result...
304 dummy_target = self.dbg.GetDummyTarget()
305 dummy_target.DeleteBreakpointName(self.bp_name_string)
307 dummy_target.GetBreakpointNames(name_list)
308 self.assertTrue(self.bp_name_string not in name_list, "Didn't delete %s from the dummy target"%(self.bp_name_string))
309 # Also make sure the name got removed from breakpoints holding it:
310 self.assertFalse(bkpt.MatchesName(self.bp_name_string), "Didn't remove the name from the breakpoint.")
312 def check_permission_results(self, bp_name):
313 self.assertEqual(bp_name.GetAllowDelete(), False, "Didn't set allow delete.")
314 protected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
315 protected_id = protected_bkpt.GetID()
317 unprotected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
318 unprotected_id = unprotected_bkpt.GetID()
320 success = protected_bkpt.AddName(self.bp_name_string)
321 self.assertTrue(success, "Couldn't add this name to the breakpoint")
323 self.target.DisableAllBreakpoints()
324 self.assertEqual(protected_bkpt.IsEnabled(), True, "Didnt' keep breakpoint from being disabled")
325 self.assertEqual(unprotected_bkpt.IsEnabled(), False, "Protected too many breakpoints from disabling.")
327 # Try from the command line too:
328 unprotected_bkpt.SetEnabled(True)
329 result = lldb.SBCommandReturnObject()
330 self.dbg.GetCommandInterpreter().HandleCommand("break disable", result)
331 self.assertTrue(result.Succeeded())
332 self.assertEqual(protected_bkpt.IsEnabled(), True, "Didnt' keep breakpoint from being disabled")
333 self.assertEqual(unprotected_bkpt.IsEnabled(), False, "Protected too many breakpoints from disabling.")
335 self.target.DeleteAllBreakpoints()
336 bkpt = self.target.FindBreakpointByID(protected_id)
337 self.assertTrue(bkpt.IsValid(), "Didn't keep the breakpoint from being deleted.")
338 bkpt = self.target.FindBreakpointByID(unprotected_id)
339 self.assertFalse(bkpt.IsValid(), "Protected too many breakpoints from deletion.")
341 # Remake the unprotected breakpoint and try again from the command line:
342 unprotected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
343 unprotected_id = unprotected_bkpt.GetID()
345 self.dbg.GetCommandInterpreter().HandleCommand("break delete -f", result)
346 self.assertTrue(result.Succeeded())
347 bkpt = self.target.FindBreakpointByID(protected_id)
348 self.assertTrue(bkpt.IsValid(), "Didn't keep the breakpoint from being deleted.")
349 bkpt = self.target.FindBreakpointByID(unprotected_id)
350 self.assertFalse(bkpt.IsValid(), "Protected too many breakpoints from deletion.")
352 def do_check_configuring_permissions_sb(self):
353 bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
355 # Make a breakpoint name with delete disallowed:
356 bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
357 self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name for valid name.")
359 bp_name.SetAllowDelete(False)
360 bp_name.SetAllowDisable(False)
361 bp_name.SetAllowList(False)
362 self.check_permission_results(bp_name)
364 def do_check_configuring_permissions_cli(self):
365 # Make the name with the right options using the command line:
366 self.runCmd("breakpoint name configure -L 0 -D 0 -A 0 %s"%(self.bp_name_string), check=True)
367 # Now look up the breakpoint we made, and check that it works.
368 bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
369 self.assertTrue(bp_name.IsValid(), "Didn't make a breakpoint name we could find.")
370 self.check_permission_results(bp_name)