brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.4 KiB · 634940d Raw
376 lines · python
1"""2Test setting breakpoints using a scripted resolver3"""4 5import os6import lldb7import lldbsuite.test.lldbutil as lldbutil8from lldbsuite.test.decorators import *9from lldbsuite.test.lldbtest import *10 11 12class TestScriptedResolver(TestBase):13    NO_DEBUG_INFO_TESTCASE = True14 15    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")16    def test_scripted_resolver(self):17        """Use a scripted resolver to set a by symbol name breakpoint"""18        self.build()19        self.do_test()20 21    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")22    def test_search_depths(self):23        """Make sure we are called at the right depths depending on what we return24        from __get_depth__"""25        self.build()26        self.do_test_depths()27 28    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")29    def test_command_line(self):30        """Test setting a resolver breakpoint from the command line"""31        self.build()32        self.do_test_cli()33 34    def test_bad_command_lines(self):35        """Make sure we get appropriate errors when we give invalid key/value36        options"""37        self.build()38        self.do_test_bad_options()39 40    def test_copy_from_dummy_target(self):41        """Make sure we don't crash during scripted breakpoint copy from dummy target"""42        self.build()43        self.do_test_copy_from_dummy_target()44 45    def make_target_and_import(self):46        target = self.make_target()47        self.import_resolver_script()48        return target49 50    def make_target(self):51        return lldbutil.run_to_breakpoint_make_target(self)52 53    def import_resolver_script(self):54        interp = self.dbg.GetCommandInterpreter()55        error = lldb.SBError()56 57        script_name = os.path.join(self.getSourceDir(), "resolver.py")58        source_name = os.path.join(self.getSourceDir(), "main.c")59 60        command = "command script import " + script_name61        result = lldb.SBCommandReturnObject()62        interp.HandleCommand(command, result)63        self.assertTrue(64            result.Succeeded(), "com scr imp failed: %s" % (result.GetError())65        )66 67    def make_extra_args(self):68        json_string = '{"symbol":"break_on_me", "test1": "value1"}'69        json_stream = lldb.SBStream()70        json_stream.Print(json_string)71        extra_args = lldb.SBStructuredData()72        error = extra_args.SetFromJSON(json_stream)73        self.assertSuccess(error, "Error making SBStructuredData")74        return extra_args75 76    def do_test(self):77        """This reads in a python file and sets a breakpoint using it."""78 79        target = self.make_target_and_import()80        extra_args = self.make_extra_args()81 82        file_list = lldb.SBFileSpecList()83        module_list = lldb.SBFileSpecList()84 85        # Make breakpoints with this resolver using different filters, first ones that will take:86        right = []87        # one with no file or module spec - this one should fire:88        right.append(89            target.BreakpointCreateFromScript(90                "resolver.Resolver", extra_args, module_list, file_list91            )92        )93 94        # one with the right source file and no module - should also fire:95        file_list.Append(lldb.SBFileSpec("main.c"))96        right.append(97            target.BreakpointCreateFromScript(98                "resolver.Resolver", extra_args, module_list, file_list99            )100        )101        # Make sure the help text shows up in the "break list" output:102        self.expect(103            "break list",104            substrs=["I am a python breakpoint resolver"],105            msg="Help is listed in break list",106        )107 108        # one with the right source file and right module - should also fire:109        module_list.Append(lldb.SBFileSpec("a.out"))110        right.append(111            target.BreakpointCreateFromScript(112                "resolver.Resolver", extra_args, module_list, file_list113            )114        )115 116        # And one with no source file but the right module:117        file_list.Clear()118        right.append(119            target.BreakpointCreateFromScript(120                "resolver.Resolver", extra_args, module_list, file_list121            )122        )123 124        # Make sure these all got locations:125        for i in range(0, len(right)):126            self.assertGreaterEqual(127                right[i].GetNumLocations(), 1, "Breakpoint %d has no locations." % (i)128            )129 130        # Now some ones that won't take:131 132        module_list.Clear()133        file_list.Clear()134        wrong = []135 136        # one with the wrong module - should not fire:137        module_list.Append(lldb.SBFileSpec("noSuchModule"))138        wrong.append(139            target.BreakpointCreateFromScript(140                "resolver.Resolver", extra_args, module_list, file_list141            )142        )143 144        # one with the wrong file - also should not fire:145        file_list.Clear()146        module_list.Clear()147        file_list.Append(lldb.SBFileSpec("noFileOfThisName.xxx"))148        wrong.append(149            target.BreakpointCreateFromScript(150                "resolver.Resolver", extra_args, module_list, file_list151            )152        )153 154        # Now make sure the CU level iteration obeys the file filters:155        file_list.Clear()156        module_list.Clear()157        file_list.Append(lldb.SBFileSpec("no_such_file.xxx"))158        wrong.append(159            target.BreakpointCreateFromScript(160                "resolver.ResolverCUDepth", extra_args, module_list, file_list161            )162        )163 164        # And the Module filters:165        file_list.Clear()166        module_list.Clear()167        module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib"))168        wrong.append(169            target.BreakpointCreateFromScript(170                "resolver.ResolverCUDepth", extra_args, module_list, file_list171            )172        )173 174        # Now make sure the Function level iteration obeys the file filters:175        file_list.Clear()176        module_list.Clear()177        file_list.Append(lldb.SBFileSpec("no_such_file.xxx"))178        wrong.append(179            target.BreakpointCreateFromScript(180                "resolver.ResolverFuncDepth", extra_args, module_list, file_list181            )182        )183 184        # And the Module filters:185        file_list.Clear()186        module_list.Clear()187        module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib"))188        wrong.append(189            target.BreakpointCreateFromScript(190                "resolver.ResolverFuncDepth", extra_args, module_list, file_list191            )192        )193 194        # Make sure these didn't get locations:195        for i in range(0, len(wrong)):196            self.assertEqual(197                wrong[i].GetNumLocations(), 0, "Breakpoint %d has locations." % (i)198            )199 200        # Now run to main and ensure we hit the breakpoints we should have:201 202        lldbutil.run_to_breakpoint_do_run(self, target, right[0])203 204        # Test the hit counts:205        for i in range(0, len(right)):206            self.assertEqual(207                right[i].GetHitCount(), 1, "Breakpoint %d has the wrong hit count" % (i)208            )209 210        for i in range(0, len(wrong)):211            self.assertEqual(212                wrong[i].GetHitCount(), 0, "Breakpoint %d has the wrong hit count" % (i)213            )214 215    def do_test_depths(self):216        """This test uses a class variable in resolver.Resolver which gets set to 1 if we saw217        compile unit and 2 if we only saw modules.  If the search depth is module, you get passed just218        the modules with no comp_unit.  If the depth is comp_unit you get comp_units.  So we can use219        this to test that our callback gets called at the right depth."""220 221        target = self.make_target_and_import()222        extra_args = self.make_extra_args()223 224        file_list = lldb.SBFileSpecList()225        module_list = lldb.SBFileSpecList()226        module_list.Append(lldb.SBFileSpec("a.out"))227 228        # Make a breakpoint that has no __get_depth__, check that that is converted to eSearchDepthModule:229        bkpt = target.BreakpointCreateFromScript(230            "resolver.Resolver", extra_args, module_list, file_list231        )232        self.assertGreater(bkpt.GetNumLocations(), 0, "Resolver got no locations.")233        self.expect(234            "script print(resolver.Resolver.got_files)",235            substrs=["2"],236            msg="Was only passed modules",237        )238        print(f"Made first breakpoint: {bkpt}")239        bkpt = None240        # Make a breakpoint that asks for modules, check that we didn't get any files:241        bkpt = target.BreakpointCreateFromScript(242            "resolver.ResolverModuleDepth", extra_args, module_list, file_list243        )244        print(f"Made Second breakpoint: {bkpt}")245        self.assertGreater(246            bkpt.GetNumLocations(), 0, "ResolverModuleDepth got no locations."247        )248        self.expect(249            "script print(resolver.Resolver.got_files)",250            substrs=["2"],251            msg="Was only passed modules",252        )253 254        # Make a breakpoint that asks for compile units, check that we didn't get any files:255        bkpt = target.BreakpointCreateFromScript(256            "resolver.ResolverCUDepth", extra_args, module_list, file_list257        )258        self.assertGreater(259            bkpt.GetNumLocations(), 0, "ResolverCUDepth got no locations."260        )261        self.expect(262            "script print(resolver.Resolver.got_files)",263            substrs=["1"],264            msg="Was passed compile units",265        )266 267        # Make a breakpoint that returns a bad value - we should convert that to "modules" so check that:268        bkpt = target.BreakpointCreateFromScript(269            "resolver.ResolverBadDepth", extra_args, module_list, file_list270        )271        self.assertGreater(272            bkpt.GetNumLocations(), 0, "ResolverBadDepth got no locations."273        )274        self.expect(275            "script print(resolver.Resolver.got_files)",276            substrs=["2"],277            msg="Was only passed modules",278        )279 280        # Make a breakpoint that searches at function depth:281        bkpt = target.BreakpointCreateFromScript(282            "resolver.ResolverFuncDepth", extra_args, module_list, file_list283        )284        self.assertGreater(285            bkpt.GetNumLocations(), 0, "ResolverFuncDepth got no locations."286        )287        self.expect(288            "script print(resolver.Resolver.got_files)",289            substrs=["3"],290            msg="Was only passed modules",291        )292        self.expect(293            "script print(resolver.Resolver.func_list)",294            substrs=["test_func", "break_on_me", "main"],295            msg="Saw all the functions",296        )297 298    def do_test_cli(self):299        target = self.make_target_and_import()300 301        lldbutil.run_break_set_by_script(302            self, "resolver.Resolver", extra_options="-k symbol -v break_on_me"303        )304 305        # Make sure setting a resolver breakpoint doesn't pollute further breakpoint setting306        # by checking the description of a regular file & line breakpoint to make sure it307        # doesn't mention the Python Resolver function:308        bkpt_no = lldbutil.run_break_set_by_file_and_line(self, "main.c", 12)309        bkpt = target.FindBreakpointByID(bkpt_no)310        strm = lldb.SBStream()311        bkpt.GetDescription(strm, False)312        used_resolver = "I am a python breakpoint resolver" in strm.GetData()313        self.assertFalse(314            used_resolver,315            "Found the resolver description in the file & line breakpoint description.",316        )317 318        # Also make sure the breakpoint was where we expected:319        bp_loc = bkpt.GetLocationAtIndex(0)320        bp_sc = bp_loc.GetAddress().GetSymbolContext(lldb.eSymbolContextEverything)321        bp_se = bp_sc.GetLineEntry()322        self.assertEqual(bp_se.GetLine(), 12, "Got the right line number")323        self.assertEqual(324            bp_se.GetFileSpec().GetFilename(), "main.c", "Got the right filename"325        )326 327    def do_test_bad_options(self):328        target = self.make_target_and_import()329 330        self.expect(331            "break set -P resolver.Resolver -k a_key",332            error=True,333            msg="Missing value at end",334            substrs=['Key: "a_key" missing value'],335        )336        self.expect(337            "break set -P resolver.Resolver -v a_value",338            error=True,339            msg="Missing key at end",340            substrs=['Value: "a_value" missing matching key'],341        )342        self.expect(343            "break set -P resolver.Resolver -v a_value -k a_key -v another_value",344            error=True,345            msg="Missing key among args",346            substrs=['Value: "a_value" missing matching key'],347        )348        self.expect(349            "break set -P resolver.Resolver -k a_key -k a_key -v another_value",350            error=True,351            msg="Missing value among args",352            substrs=['Key: "a_key" missing value'],353        )354 355    def do_test_copy_from_dummy_target(self):356        # Import breakpoint scripted resolver.357        self.import_resolver_script()358 359        # Create a scripted breakpoint.360        self.runCmd(361            "breakpoint set -P resolver.Resolver -k symbol -v break_on_me",362            BREAKPOINT_CREATED,363        )364 365        # This is the function to remove breakpoints from the dummy target366        # to get a clean state for the next test case.367        def cleanup():368            self.runCmd("breakpoint delete -D -f", check=False)369            self.runCmd("breakpoint list", check=False)370 371        # Execute the cleanup function during test case tear down.372        self.addTearDownHook(cleanup)373 374        # Check that target creating doesn't crash.375        target = self.make_target()376