199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest setting breakpoints using a scripted resolver 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprechtimport os 699451b44SJordan Rupprechtimport lldb 799451b44SJordan Rupprechtimport lldbsuite.test.lldbutil as lldbutil 899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprecht 1299451b44SJordan Rupprechtclass TestScriptedResolver(TestBase): 1399451b44SJordan Rupprecht 1499451b44SJordan Rupprecht mydir = TestBase.compute_mydir(__file__) 1599451b44SJordan Rupprecht 1699451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1799451b44SJordan Rupprecht 1899451b44SJordan Rupprecht @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528") 1999451b44SJordan Rupprecht def test_scripted_resolver(self): 2099451b44SJordan Rupprecht """Use a scripted resolver to set a by symbol name breakpoint""" 2199451b44SJordan Rupprecht self.build() 2299451b44SJordan Rupprecht self.do_test() 2399451b44SJordan Rupprecht 2499451b44SJordan Rupprecht @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528") 2599451b44SJordan Rupprecht def test_search_depths(self): 2699451b44SJordan Rupprecht """ Make sure we are called at the right depths depending on what we return 2799451b44SJordan Rupprecht from __get_depth__""" 2899451b44SJordan Rupprecht self.build() 2999451b44SJordan Rupprecht self.do_test_depths() 3099451b44SJordan Rupprecht 3199451b44SJordan Rupprecht @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528") 3299451b44SJordan Rupprecht def test_command_line(self): 3399451b44SJordan Rupprecht """ Test setting a resolver breakpoint from the command line """ 3499451b44SJordan Rupprecht self.build() 3599451b44SJordan Rupprecht self.do_test_cli() 3699451b44SJordan Rupprecht 3799451b44SJordan Rupprecht def test_bad_command_lines(self): 3899451b44SJordan Rupprecht """Make sure we get appropriate errors when we give invalid key/value 3999451b44SJordan Rupprecht options""" 4099451b44SJordan Rupprecht self.build() 4199451b44SJordan Rupprecht self.do_test_bad_options() 4299451b44SJordan Rupprecht 43185ef697STatyana Krasnukha def test_copy_from_dummy_target(self): 44185ef697STatyana Krasnukha """Make sure we don't crash during scripted breakpoint copy from dummy target""" 45185ef697STatyana Krasnukha self.build() 46185ef697STatyana Krasnukha self.do_test_copy_from_dummy_target() 47185ef697STatyana Krasnukha 4899451b44SJordan Rupprecht def make_target_and_import(self): 49185ef697STatyana Krasnukha target = self.make_target() 50185ef697STatyana Krasnukha self.import_resolver_script() 51185ef697STatyana Krasnukha return target 52185ef697STatyana Krasnukha 53185ef697STatyana Krasnukha def make_target(self): 54185ef697STatyana Krasnukha return lldbutil.run_to_breakpoint_make_target(self) 55185ef697STatyana Krasnukha 56185ef697STatyana Krasnukha def import_resolver_script(self): 5799451b44SJordan Rupprecht interp = self.dbg.GetCommandInterpreter() 5899451b44SJordan Rupprecht error = lldb.SBError() 5999451b44SJordan Rupprecht 6099451b44SJordan Rupprecht script_name = os.path.join(self.getSourceDir(), "resolver.py") 6199451b44SJordan Rupprecht source_name = os.path.join(self.getSourceDir(), "main.c") 6299451b44SJordan Rupprecht 6399451b44SJordan Rupprecht command = "command script import " + script_name 6499451b44SJordan Rupprecht result = lldb.SBCommandReturnObject() 6599451b44SJordan Rupprecht interp.HandleCommand(command, result) 6699451b44SJordan Rupprecht self.assertTrue(result.Succeeded(), "com scr imp failed: %s"%(result.GetError())) 6799451b44SJordan Rupprecht 6899451b44SJordan Rupprecht def make_extra_args(self): 6999451b44SJordan Rupprecht json_string = '{"symbol":"break_on_me", "test1": "value1"}' 7099451b44SJordan Rupprecht json_stream = lldb.SBStream() 7199451b44SJordan Rupprecht json_stream.Print(json_string) 7299451b44SJordan Rupprecht extra_args = lldb.SBStructuredData() 7399451b44SJordan Rupprecht error = extra_args.SetFromJSON(json_stream) 74*779bbbf2SDave Lee self.assertSuccess(error, "Error making SBStructuredData") 7599451b44SJordan Rupprecht return extra_args 7699451b44SJordan Rupprecht 7799451b44SJordan Rupprecht def do_test(self): 7899451b44SJordan Rupprecht """This reads in a python file and sets a breakpoint using it.""" 7999451b44SJordan Rupprecht 8099451b44SJordan Rupprecht target = self.make_target_and_import() 8199451b44SJordan Rupprecht extra_args = self.make_extra_args() 8299451b44SJordan Rupprecht 8399451b44SJordan Rupprecht file_list = lldb.SBFileSpecList() 8499451b44SJordan Rupprecht module_list = lldb.SBFileSpecList() 8599451b44SJordan Rupprecht 8699451b44SJordan Rupprecht # Make breakpoints with this resolver using different filters, first ones that will take: 8799451b44SJordan Rupprecht right = [] 8899451b44SJordan Rupprecht # one with no file or module spec - this one should fire: 8999451b44SJordan Rupprecht right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) 9099451b44SJordan Rupprecht 9199451b44SJordan Rupprecht # one with the right source file and no module - should also fire: 9299451b44SJordan Rupprecht file_list.Append(lldb.SBFileSpec("main.c")) 9399451b44SJordan Rupprecht right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) 9499451b44SJordan Rupprecht # Make sure the help text shows up in the "break list" output: 9599451b44SJordan Rupprecht self.expect("break list", substrs=["I am a python breakpoint resolver"], msg="Help is listed in break list") 9699451b44SJordan Rupprecht 9799451b44SJordan Rupprecht # one with the right source file and right module - should also fire: 9899451b44SJordan Rupprecht module_list.Append(lldb.SBFileSpec("a.out")) 9999451b44SJordan Rupprecht right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) 10099451b44SJordan Rupprecht 10199451b44SJordan Rupprecht # And one with no source file but the right module: 10299451b44SJordan Rupprecht file_list.Clear() 10399451b44SJordan Rupprecht right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) 10499451b44SJordan Rupprecht 10599451b44SJordan Rupprecht # Make sure these all got locations: 10699451b44SJordan Rupprecht for i in range (0, len(right)): 10799451b44SJordan Rupprecht self.assertTrue(right[i].GetNumLocations() >= 1, "Breakpoint %d has no locations."%(i)) 10899451b44SJordan Rupprecht 10999451b44SJordan Rupprecht # Now some ones that won't take: 11099451b44SJordan Rupprecht 11199451b44SJordan Rupprecht module_list.Clear() 11299451b44SJordan Rupprecht file_list.Clear() 11399451b44SJordan Rupprecht wrong = [] 11499451b44SJordan Rupprecht 11599451b44SJordan Rupprecht # one with the wrong module - should not fire: 11699451b44SJordan Rupprecht module_list.Append(lldb.SBFileSpec("noSuchModule")) 11799451b44SJordan Rupprecht wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) 11899451b44SJordan Rupprecht 11999451b44SJordan Rupprecht # one with the wrong file - also should not fire: 12099451b44SJordan Rupprecht file_list.Clear() 12199451b44SJordan Rupprecht module_list.Clear() 12299451b44SJordan Rupprecht file_list.Append(lldb.SBFileSpec("noFileOfThisName.xxx")) 12399451b44SJordan Rupprecht wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) 12499451b44SJordan Rupprecht 12599451b44SJordan Rupprecht # Now make sure the CU level iteration obeys the file filters: 12699451b44SJordan Rupprecht file_list.Clear() 12799451b44SJordan Rupprecht module_list.Clear() 12899451b44SJordan Rupprecht file_list.Append(lldb.SBFileSpec("no_such_file.xxx")) 12999451b44SJordan Rupprecht wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list)) 13099451b44SJordan Rupprecht 13199451b44SJordan Rupprecht # And the Module filters: 13299451b44SJordan Rupprecht file_list.Clear() 13399451b44SJordan Rupprecht module_list.Clear() 13499451b44SJordan Rupprecht module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib")) 13599451b44SJordan Rupprecht wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list)) 13699451b44SJordan Rupprecht 13799451b44SJordan Rupprecht # Now make sure the Function level iteration obeys the file filters: 13899451b44SJordan Rupprecht file_list.Clear() 13999451b44SJordan Rupprecht module_list.Clear() 14099451b44SJordan Rupprecht file_list.Append(lldb.SBFileSpec("no_such_file.xxx")) 14199451b44SJordan Rupprecht wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list)) 14299451b44SJordan Rupprecht 14399451b44SJordan Rupprecht # And the Module filters: 14499451b44SJordan Rupprecht file_list.Clear() 14599451b44SJordan Rupprecht module_list.Clear() 14699451b44SJordan Rupprecht module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib")) 14799451b44SJordan Rupprecht wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list)) 14899451b44SJordan Rupprecht 14999451b44SJordan Rupprecht # Make sure these didn't get locations: 15099451b44SJordan Rupprecht for i in range(0, len(wrong)): 15199451b44SJordan Rupprecht self.assertEqual(wrong[i].GetNumLocations(), 0, "Breakpoint %d has locations."%(i)) 15299451b44SJordan Rupprecht 15399451b44SJordan Rupprecht # Now run to main and ensure we hit the breakpoints we should have: 15499451b44SJordan Rupprecht 15599451b44SJordan Rupprecht lldbutil.run_to_breakpoint_do_run(self, target, right[0]) 15699451b44SJordan Rupprecht 15799451b44SJordan Rupprecht # Test the hit counts: 15899451b44SJordan Rupprecht for i in range(0, len(right)): 15999451b44SJordan Rupprecht self.assertEqual(right[i].GetHitCount(), 1, "Breakpoint %d has the wrong hit count"%(i)) 16099451b44SJordan Rupprecht 16199451b44SJordan Rupprecht for i in range(0, len(wrong)): 16299451b44SJordan Rupprecht self.assertEqual(wrong[i].GetHitCount(), 0, "Breakpoint %d has the wrong hit count"%(i)) 16399451b44SJordan Rupprecht 16499451b44SJordan Rupprecht def do_test_depths(self): 16599451b44SJordan Rupprecht """This test uses a class variable in resolver.Resolver which gets set to 1 if we saw 16699451b44SJordan Rupprecht compile unit and 2 if we only saw modules. If the search depth is module, you get passed just 16799451b44SJordan Rupprecht the modules with no comp_unit. If the depth is comp_unit you get comp_units. So we can use 16899451b44SJordan Rupprecht this to test that our callback gets called at the right depth.""" 16999451b44SJordan Rupprecht 17099451b44SJordan Rupprecht target = self.make_target_and_import() 17199451b44SJordan Rupprecht extra_args = self.make_extra_args() 17299451b44SJordan Rupprecht 17399451b44SJordan Rupprecht file_list = lldb.SBFileSpecList() 17499451b44SJordan Rupprecht module_list = lldb.SBFileSpecList() 17599451b44SJordan Rupprecht module_list.Append(lldb.SBFileSpec("a.out")) 17699451b44SJordan Rupprecht 17799451b44SJordan Rupprecht # Make a breakpoint that has no __get_depth__, check that that is converted to eSearchDepthModule: 17899451b44SJordan Rupprecht bkpt = target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list) 17999451b44SJordan Rupprecht self.assertTrue(bkpt.GetNumLocations() > 0, "Resolver got no locations.") 18099451b44SJordan Rupprecht self.expect("script print(resolver.Resolver.got_files)", substrs=["2"], msg="Was only passed modules") 18199451b44SJordan Rupprecht 18299451b44SJordan Rupprecht # Make a breakpoint that asks for modules, check that we didn't get any files: 18399451b44SJordan Rupprecht bkpt = target.BreakpointCreateFromScript("resolver.ResolverModuleDepth", extra_args, module_list, file_list) 18499451b44SJordan Rupprecht self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverModuleDepth got no locations.") 18599451b44SJordan Rupprecht self.expect("script print(resolver.Resolver.got_files)", substrs=["2"], msg="Was only passed modules") 18699451b44SJordan Rupprecht 18799451b44SJordan Rupprecht # Make a breakpoint that asks for compile units, check that we didn't get any files: 18899451b44SJordan Rupprecht bkpt = target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list) 18999451b44SJordan Rupprecht self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverCUDepth got no locations.") 19099451b44SJordan Rupprecht self.expect("script print(resolver.Resolver.got_files)", substrs=["1"], msg="Was passed compile units") 19199451b44SJordan Rupprecht 19299451b44SJordan Rupprecht # Make a breakpoint that returns a bad value - we should convert that to "modules" so check that: 19399451b44SJordan Rupprecht bkpt = target.BreakpointCreateFromScript("resolver.ResolverBadDepth", extra_args, module_list, file_list) 19499451b44SJordan Rupprecht self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverBadDepth got no locations.") 19599451b44SJordan Rupprecht self.expect("script print(resolver.Resolver.got_files)", substrs=["2"], msg="Was only passed modules") 19699451b44SJordan Rupprecht 19799451b44SJordan Rupprecht # Make a breakpoint that searches at function depth: 19899451b44SJordan Rupprecht bkpt = target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list) 19999451b44SJordan Rupprecht self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverFuncDepth got no locations.") 20099451b44SJordan Rupprecht self.expect("script print(resolver.Resolver.got_files)", substrs=["3"], msg="Was only passed modules") 20199451b44SJordan Rupprecht self.expect("script print(resolver.Resolver.func_list)", substrs=['test_func', 'break_on_me', 'main'], msg="Saw all the functions") 20299451b44SJordan Rupprecht 20399451b44SJordan Rupprecht def do_test_cli(self): 20499451b44SJordan Rupprecht target = self.make_target_and_import() 20599451b44SJordan Rupprecht 20699451b44SJordan Rupprecht lldbutil.run_break_set_by_script(self, "resolver.Resolver", extra_options="-k symbol -v break_on_me") 20799451b44SJordan Rupprecht 20899451b44SJordan Rupprecht # Make sure setting a resolver breakpoint doesn't pollute further breakpoint setting 20999451b44SJordan Rupprecht # by checking the description of a regular file & line breakpoint to make sure it 21099451b44SJordan Rupprecht # doesn't mention the Python Resolver function: 21199451b44SJordan Rupprecht bkpt_no = lldbutil.run_break_set_by_file_and_line(self, "main.c", 12) 21299451b44SJordan Rupprecht bkpt = target.FindBreakpointByID(bkpt_no) 21399451b44SJordan Rupprecht strm = lldb.SBStream() 21499451b44SJordan Rupprecht bkpt.GetDescription(strm, False) 21599451b44SJordan Rupprecht used_resolver = "I am a python breakpoint resolver" in strm.GetData() 21699451b44SJordan Rupprecht self.assertFalse(used_resolver, "Found the resolver description in the file & line breakpoint description.") 21799451b44SJordan Rupprecht 21899451b44SJordan Rupprecht # Also make sure the breakpoint was where we expected: 21999451b44SJordan Rupprecht bp_loc = bkpt.GetLocationAtIndex(0) 22099451b44SJordan Rupprecht bp_sc = bp_loc.GetAddress().GetSymbolContext(lldb.eSymbolContextEverything) 22199451b44SJordan Rupprecht bp_se = bp_sc.GetLineEntry() 22299451b44SJordan Rupprecht self.assertEqual(bp_se.GetLine(), 12, "Got the right line number") 22399451b44SJordan Rupprecht self.assertEqual(bp_se.GetFileSpec().GetFilename(), "main.c", "Got the right filename") 22499451b44SJordan Rupprecht 22599451b44SJordan Rupprecht def do_test_bad_options(self): 22699451b44SJordan Rupprecht target = self.make_target_and_import() 22799451b44SJordan Rupprecht 22899451b44SJordan Rupprecht self.expect("break set -P resolver.Resolver -k a_key", error = True, msg="Missing value at end", 22999451b44SJordan Rupprecht substrs=['Key: "a_key" missing value']) 23099451b44SJordan Rupprecht self.expect("break set -P resolver.Resolver -v a_value", error = True, msg="Missing key at end", 23199451b44SJordan Rupprecht substrs=['Value: "a_value" missing matching key']) 23299451b44SJordan Rupprecht self.expect("break set -P resolver.Resolver -v a_value -k a_key -v another_value", error = True, msg="Missing key among args", 23399451b44SJordan Rupprecht substrs=['Value: "a_value" missing matching key']) 23499451b44SJordan Rupprecht self.expect("break set -P resolver.Resolver -k a_key -k a_key -v another_value", error = True, msg="Missing value among args", 23599451b44SJordan Rupprecht substrs=['Key: "a_key" missing value']) 236185ef697STatyana Krasnukha 237185ef697STatyana Krasnukha def do_test_copy_from_dummy_target(self): 238185ef697STatyana Krasnukha # Import breakpoint scripted resolver. 239185ef697STatyana Krasnukha self.import_resolver_script() 240185ef697STatyana Krasnukha 241185ef697STatyana Krasnukha # Create a scripted breakpoint. 242185ef697STatyana Krasnukha self.runCmd("breakpoint set -P resolver.Resolver -k symbol -v break_on_me", 243185ef697STatyana Krasnukha BREAKPOINT_CREATED) 244185ef697STatyana Krasnukha 245185ef697STatyana Krasnukha # This is the function to remove breakpoints from the dummy target 246185ef697STatyana Krasnukha # to get a clean state for the next test case. 247185ef697STatyana Krasnukha def cleanup(): 248185ef697STatyana Krasnukha self.runCmd('breakpoint delete -D -f', check=False) 249185ef697STatyana Krasnukha self.runCmd('breakpoint list', check=False) 250185ef697STatyana Krasnukha 251185ef697STatyana Krasnukha # Execute the cleanup function during test case tear down. 252185ef697STatyana Krasnukha self.addTearDownHook(cleanup) 253185ef697STatyana Krasnukha 254185ef697STatyana Krasnukha # Check that target creating doesn't crash. 255185ef697STatyana Krasnukha target = self.make_target() 256