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