2 Test breakpoint serialization.
7 from lldbsuite.test.decorators import *
8 from lldbsuite.test.lldbtest import *
9 from lldbsuite.test import lldbutil
12 class BreakpointSerialization(TestBase):
14 mydir = TestBase.compute_mydir(__file__)
15 NO_DEBUG_INFO_TESTCASE = True
17 @add_test_categories(['pyapi'])
18 def test_resolvers(self):
19 """Use Python APIs to test that we serialize resolvers."""
21 self.setup_targets_and_cleanup()
22 self.do_check_resolvers()
24 def test_filters(self):
25 """Use Python APIs to test that we serialize search filters correctly."""
27 self.setup_targets_and_cleanup()
28 self.do_check_filters()
30 def test_options(self):
31 """Use Python APIs to test that we serialize breakpoint options correctly."""
33 self.setup_targets_and_cleanup()
34 self.do_check_options()
36 def test_appending(self):
37 """Use Python APIs to test that we serialize breakpoint options correctly."""
39 self.setup_targets_and_cleanup()
40 self.do_check_appending()
42 def test_name_filters(self):
43 """Use python APIs to test that reading in by name works correctly."""
45 self.setup_targets_and_cleanup()
48 def test_scripted_extra_args(self):
50 self.setup_targets_and_cleanup()
51 self.do_check_extra_args()
53 def setup_targets_and_cleanup(self):
55 self.RemoveTempFile(self.bkpts_file_path)
57 if self.orig_target.IsValid():
58 self.dbg.DeleteTarget(self.orig_target)
59 self.dbg.DeleteTarget(self.copy_target)
61 self.addTearDownHook(cleanup)
62 self.RemoveTempFile(self.bkpts_file_path)
64 exe = self.getBuildArtifact("a.out")
66 # Create the targets we are making breakpoints in and copying them to:
67 self.orig_target = self.dbg.CreateTarget(exe)
68 self.assertTrue(self.orig_target, VALID_TARGET)
70 self.copy_target = self.dbg.CreateTarget(exe)
71 self.assertTrue(self.copy_target, VALID_TARGET)
74 # Call super's setUp().
77 self.bkpts_file_path = self.getBuildArtifact("breakpoints.json")
78 self.bkpts_file_spec = lldb.SBFileSpec(self.bkpts_file_path)
80 def check_equivalence(self, source_bps, do_write = True):
82 error = lldb.SBError()
85 error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps)
86 self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
88 copy_bps = lldb.SBBreakpointList(self.copy_target)
89 error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, copy_bps)
90 self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString()))
92 num_source_bps = source_bps.GetSize()
93 num_copy_bps = copy_bps.GetSize()
94 self.assertTrue(num_source_bps == num_copy_bps, "Didn't get same number of input and output breakpoints - orig: %d copy: %d"%(num_source_bps, num_copy_bps))
96 for i in range(0, num_source_bps):
97 source_bp = source_bps.GetBreakpointAtIndex(i)
98 source_desc = lldb.SBStream()
99 source_bp.GetDescription(source_desc, False)
100 source_text = source_desc.GetData()
102 # I am assuming here that the breakpoints will get written out in breakpoint ID order, and
103 # read back in ditto. That is true right now, and I can't see any reason to do it differently
104 # but if we do we can go to writing the breakpoints one by one, or sniffing the descriptions to
105 # see which one is which.
106 copy_id = source_bp.GetID()
107 copy_bp = copy_bps.FindBreakpointByID(copy_id)
108 self.assertTrue(copy_bp.IsValid(), "Could not find copy breakpoint %d."%(copy_id))
110 copy_desc = lldb.SBStream()
111 copy_bp.GetDescription(copy_desc, False)
112 copy_text = copy_desc.GetData()
114 # These two should be identical.
115 # print ("Source text for %d is %s."%(i, source_text))
116 self.assertTrue (source_text == copy_text, "Source and dest breakpoints are not identical: \nsource: %s\ndest: %s"%(source_text, copy_text))
118 def do_check_resolvers(self):
119 """Use Python APIs to check serialization of breakpoint resolvers"""
121 empty_module_list = lldb.SBFileSpecList()
122 empty_cu_list = lldb.SBFileSpecList()
123 blubby_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "blubby.c"))
125 # It isn't actually important for these purposes that these breakpoint
126 # actually have locations.
127 source_bps = lldb.SBBreakpointList(self.orig_target)
128 source_bps.Append(self.orig_target.BreakpointCreateByLocation("blubby.c", 666))
129 # Make sure we do one breakpoint right:
130 self.check_equivalence(source_bps)
133 source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list))
134 source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list))
135 source_bps.Append(self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec))
137 # And some number greater than one:
138 self.check_equivalence(source_bps)
140 def do_check_filters(self):
141 """Use Python APIs to check serialization of breakpoint filters."""
142 module_list = lldb.SBFileSpecList()
143 module_list.Append(lldb.SBFileSpec("SomeBinary"))
144 module_list.Append(lldb.SBFileSpec("SomeOtherBinary"))
146 cu_list = lldb.SBFileSpecList()
147 cu_list.Append(lldb.SBFileSpec("SomeCU.c"))
148 cu_list.Append(lldb.SBFileSpec("AnotherCU.c"))
149 cu_list.Append(lldb.SBFileSpec("ThirdCU.c"))
151 blubby_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "blubby.c"))
153 # It isn't actually important for these purposes that these breakpoint
154 # actually have locations.
155 source_bps = lldb.SBBreakpointList(self.orig_target)
156 bkpt = self.orig_target.BreakpointCreateByLocation(blubby_file_spec, 666, 0, module_list)
157 source_bps.Append(bkpt)
159 # Make sure we do one right:
160 self.check_equivalence(source_bps)
163 bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, module_list, cu_list)
164 source_bps.Append(bkpt)
165 bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, module_list, cu_list)
166 source_bps.Append(bkpt)
167 bkpt = self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec)
168 source_bps.Append(bkpt)
170 # And some number greater than one:
171 self.check_equivalence(source_bps)
173 def do_check_options(self):
174 """Use Python APIs to check serialization of breakpoint options."""
176 empty_module_list = lldb.SBFileSpecList()
177 empty_cu_list = lldb.SBFileSpecList()
178 blubby_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "blubby.c"))
180 # It isn't actually important for these purposes that these breakpoint
181 # actually have locations.
182 source_bps = lldb.SBBreakpointList(self.orig_target)
184 bkpt = self.orig_target.BreakpointCreateByLocation(
185 lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList())
186 bkpt.SetEnabled(False)
187 bkpt.SetOneShot(True)
189 source_bps.Append(bkpt)
191 # Make sure we get one right:
192 self.check_equivalence(source_bps)
195 bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)
196 bkpt.SetIgnoreCount(10)
197 bkpt.SetThreadName("grubby")
198 source_bps.Append(bkpt)
200 bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)
201 bkpt.SetCondition("gonna remove this")
202 bkpt.SetCondition("")
203 source_bps.Append(bkpt)
205 bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list)
206 bkpt.SetCondition("something != something_else")
207 bkpt.SetQueueName("grubby")
208 bkpt.AddName("FirstName")
209 bkpt.AddName("SecondName")
210 bkpt.SetScriptCallbackBody('\tprint("I am a function that prints.")\n\tprint("I don\'t do anything else")\n')
211 source_bps.Append(bkpt)
213 bkpt = self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec)
214 cmd_list = lldb.SBStringList()
215 cmd_list.AppendString("frame var")
216 cmd_list.AppendString("thread backtrace")
218 bkpt.SetCommandLineCommands(cmd_list)
219 source_bps.Append(bkpt)
221 self.check_equivalence(source_bps)
223 def do_check_appending(self):
224 """Use Python APIs to check appending to already serialized options."""
226 empty_module_list = lldb.SBFileSpecList()
227 empty_cu_list = lldb.SBFileSpecList()
228 blubby_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "blubby.c"))
230 # It isn't actually important for these purposes that these breakpoint
231 # actually have locations.
233 all_bps = lldb.SBBreakpointList(self.orig_target)
234 source_bps = lldb.SBBreakpointList(self.orig_target)
236 bkpt = self.orig_target.BreakpointCreateByLocation(
237 lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList())
238 bkpt.SetEnabled(False)
239 bkpt.SetOneShot(True)
241 source_bps.Append(bkpt)
244 error = lldb.SBError()
245 error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps)
246 self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
250 bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)
251 bkpt.SetIgnoreCount(10)
252 bkpt.SetThreadName("grubby")
253 source_bps.Append(bkpt)
256 bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list)
257 bkpt.SetCondition("something != something_else")
258 bkpt.SetQueueName("grubby")
259 bkpt.AddName("FirstName")
260 bkpt.AddName("SecondName")
262 source_bps.Append(bkpt)
265 error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps, True)
266 self.assertTrue(error.Success(), "Failed appending breakpoints to file: %s."%(error.GetCString()))
268 self.check_equivalence(all_bps)
270 def do_check_names(self):
271 bkpt = self.orig_target.BreakpointCreateByLocation(
272 lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList())
273 good_bkpt_name = "GoodBreakpoint"
274 write_bps = lldb.SBBreakpointList(self.orig_target)
275 bkpt.AddName(good_bkpt_name)
276 write_bps.Append(bkpt)
278 error = lldb.SBError()
279 error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps)
280 self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
282 copy_bps = lldb.SBBreakpointList(self.copy_target)
283 names_list = lldb.SBStringList()
284 names_list.AppendString("NoSuchName")
286 error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, names_list, copy_bps)
287 self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString()))
288 self.assertTrue(copy_bps.GetSize() == 0, "Found breakpoints with a nonexistent name.")
290 names_list.AppendString(good_bkpt_name)
291 error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, names_list, copy_bps)
292 self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString()))
293 self.assertTrue(copy_bps.GetSize() == 1, "Found the matching breakpoint.")
295 def do_check_extra_args(self):
298 interp = self.dbg.GetCommandInterpreter()
299 error = lldb.SBError()
301 script_name = os.path.join(self.getSourceDir(), "resolver.py")
303 command = "command script import " + script_name
304 result = lldb.SBCommandReturnObject()
305 interp.HandleCommand(command, result)
306 self.assertTrue(result.Succeeded(), "com scr imp failed: %s"%(result.GetError()))
308 # First make sure a scripted breakpoint with no args works:
309 bkpt = self.orig_target.BreakpointCreateFromScript("resolver.Resolver", lldb.SBStructuredData(),
310 lldb.SBFileSpecList(), lldb.SBFileSpecList())
311 self.assertTrue(bkpt.IsValid(), "Bkpt is valid")
312 write_bps = lldb.SBBreakpointList(self.orig_target)
314 error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps)
315 self.assertTrue(error.Success(), "Failed writing breakpoints: %s"%(error.GetCString()))
317 side_effect.g_extra_args = None
318 copy_bps = lldb.SBBreakpointList(self.copy_target)
319 error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, copy_bps)
320 self.assertTrue(error.Success(), "Failed reading breakpoints: %s"%(error.GetCString()))
322 self.assertEqual(copy_bps.GetSize(), 1, "Got one breakpoint from file.")
323 no_keys = lldb.SBStringList()
324 side_effect.g_extra_args.GetKeys(no_keys)
325 self.assertEqual(no_keys.GetSize(), 0, "Should have no keys")
327 self.orig_target.DeleteAllBreakpoints()
328 self.copy_target.DeleteAllBreakpoints()
330 # Now try one with extra args:
332 extra_args = lldb.SBStructuredData()
333 stream = lldb.SBStream()
334 stream.Print('{"first_arg" : "first_value", "second_arg" : "second_value"}')
335 extra_args.SetFromJSON(stream)
336 self.assertTrue(extra_args.IsValid(), "SBStructuredData is valid.")
338 bkpt = self.orig_target.BreakpointCreateFromScript("resolver.Resolver",
339 extra_args, lldb.SBFileSpecList(), lldb.SBFileSpecList())
340 self.assertTrue(bkpt.IsValid(), "Bkpt is valid")
341 write_bps = lldb.SBBreakpointList(self.orig_target)
343 error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps)
344 self.assertTrue(error.Success(), "Failed writing breakpoints: %s"%(error.GetCString()))
346 orig_extra_args = side_effect.g_extra_args
347 self.assertTrue(orig_extra_args.IsValid(), "Extra args originally valid")
349 orig_keys = lldb.SBStringList()
350 orig_extra_args.GetKeys(orig_keys)
351 self.assertEqual(2, orig_keys.GetSize(), "Should have two keys")
353 side_effect.g_extra_args = None
355 copy_bps = lldb.SBBreakpointList(self.copy_target)
356 error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, copy_bps)
357 self.assertTrue(error.Success(), "Failed reading breakpoints: %s"%(error.GetCString()))
359 self.assertEqual(copy_bps.GetSize(), 1, "Got one breakpoint from file.")
361 copy_extra_args = side_effect.g_extra_args
362 copy_keys = lldb.SBStringList()
363 copy_extra_args.GetKeys(copy_keys)
364 self.assertEqual(2, copy_keys.GetSize(), "Copy should have two keys")
366 for idx in range(0, orig_keys.GetSize()):
367 key = orig_keys.GetStringAtIndex(idx)
368 copy_value = copy_extra_args.GetValueForKey(key).GetStringValue(100)
370 if key == "first_arg":
371 self.assertEqual(copy_value, "first_value")
372 elif key == "second_arg":
373 self.assertEqual(copy_value, "second_value")
375 self.Fail("Unknown key: %s"%(key))