brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.7 KiB · fdd5216 Raw
233 lines · python
1"""2Test lldb Python commands.3"""4 5 6import sys7import lldb8from lldbsuite.test.decorators import *9from lldbsuite.test.lldbtest import *10 11 12class CmdPythonTestCase(TestBase):13    NO_DEBUG_INFO_TESTCASE = True14 15    def test(self):16        self.build()17        self.pycmd_tests()18 19    def pycmd_tests(self):20        self.runCmd("command source py_import")21 22        # Test that we did indeed add these commands as user commands:23        interp = self.dbg.GetCommandInterpreter()24        self.assertTrue(interp.UserCommandExists("foobar"), "foobar exists")25        self.assertFalse(interp.CommandExists("foobar"), "It is not a builtin.")26 27        # Test a bunch of different kinds of python callables with28        # both 4 and 5 positional arguments.29        self.expect("foobar", substrs=["All good"])30        self.expect("foobar4", substrs=["All good"])31        self.expect("vfoobar", substrs=["All good"])32        self.expect("v5foobar", substrs=["All good"])33        self.expect("sfoobar", substrs=["All good"])34        self.expect("cfoobar", substrs=["All good"])35        self.expect("ifoobar", substrs=["All good"])36        self.expect("sfoobar4", substrs=["All good"])37        self.expect("cfoobar4", substrs=["All good"])38        self.expect("ifoobar4", substrs=["All good"])39        self.expect("ofoobar", substrs=["All good"])40        self.expect("ofoobar4", substrs=["All good"])41 42        # Verify command that specifies eCommandRequiresTarget returns failure43        # without a target.44        self.expect("targetname", substrs=["a.out"], matching=False, error=True)45 46        exe = self.getBuildArtifact("a.out")47        self.expect("file " + exe, patterns=["Current executable set to .*a.out"])48 49        self.expect("targetname", substrs=["a.out"], matching=True, error=False)50 51        # This is the function to remove the custom commands in order to have a52        # clean slate for the next test case.53        def cleanup():54            self.runCmd("command script delete welcome", check=False)55            self.runCmd("command script delete targetname", check=False)56            self.runCmd("command script delete longwait", check=False)57            self.runCmd("command script delete mysto", check=False)58            self.runCmd("command script delete tell_sync", check=False)59            self.runCmd("command script delete tell_async", check=False)60            self.runCmd("command script delete tell_curr", check=False)61            self.runCmd("command script delete bug11569", check=False)62            self.runCmd("command script delete takes_exe_ctx", check=False)63            self.runCmd("command script delete decorated", check=False)64 65        # Execute the cleanup function during test case tear down.66        self.addTearDownHook(cleanup)67 68        # Interact with debugger in synchronous mode69        self.setAsync(False)70 71        # We don't want to display the stdout if not in TraceOn() mode.72        if not self.TraceOn():73            self.HideStdout()74 75        self.expect("welcome Enrico", substrs=["Hello Enrico, welcome to LLDB"])76 77        self.expect(78            "help welcome",79            substrs=[80                "Just a docstring for welcome_impl",81                "A command that says hello to LLDB users",82            ],83        )84 85        decorated_commands = ["decorated" + str(n) for n in range(1, 5)]86        for name in decorated_commands:87            self.expect(name, substrs=["hello from " + name])88            self.expect(89                "help " + name, substrs=["Python command defined by @lldb.command"]90            )91 92        self.expect(93            "help",94            substrs=["For more information run"] + decorated_commands + ["welcome"],95        )96 97        self.expect(98            "help -a",99            substrs=["For more information run"] + decorated_commands + ["welcome"],100        )101 102        self.expect("help -u", matching=False, substrs=["For more information run"])103 104        self.runCmd("command script delete welcome")105 106        self.expect(107            "welcome Enrico",108            matching=False,109            error=True,110            substrs=["Hello Enrico, welcome to LLDB"],111        )112 113        self.expect(114            "targetname fail", error=True, substrs=["a test for error in command"]115        )116 117        self.expect(118            "command script list", substrs=["targetname", "For more information run"]119        )120 121        self.expect(122            "help targetname",123            substrs=["Expects", "'raw'", "input", "help", "raw-input"],124        )125 126        self.expect("longwait", substrs=["Done; if you saw the delays I am doing OK"])127 128        self.runCmd("break set -f main.cpp -l 48")129        self.runCmd("run")130        self.runCmd("mysto 3")131        self.expect(132            "frame variable array",133            substrs=["[0] = 79630", "[1] = 388785018", "[2] = 0"],134        )135        self.runCmd("mysto 3")136        self.expect(137            "frame variable array",138            substrs=["[0] = 79630", "[4] = 388785018", "[5] = 0"],139        )140 141        # we cannot use the stepover command to check for async execution mode since LLDB142        # seems to get confused when events start to queue up143        self.expect("tell_sync", substrs=["running sync"])144        self.expect("tell_async", substrs=["running async"])145        self.expect("tell_curr", substrs=["I am running sync"])146 147        # check that the execution context is passed in to commands that ask for it148        self.expect("takes_exe_ctx", substrs=["a.out"])149 150        # Test that a python command can redefine itself151        self.expect('command script add -f foobar welcome -h "just some help"')152 153        self.runCmd("command script clear")154 155        # Test that re-defining an existing command works156        self.runCmd("command script add my_command --class welcome.WelcomeCommand")157        self.expect("my_command Blah", substrs=["Hello Blah, welcome to LLDB"])158 159        self.runCmd(160            "command script add my_command -o --class welcome.TargetnameCommand"161        )162        self.expect("my_command", substrs=["a.out"])163 164        # Test that without --overwrite we are not allowed to redefine the command.165        self.expect(166            "command script add my_command --class welcome.TargetnameCommand",167            substrs=[168                (169                    'user command "my_command" already exists and force replace was'170                    " not set by --overwrite or 'settings set"171                    " interpreter.require-overwrite false'"172                ),173            ],174            error=True,175        )176 177        self.runCmd("command script clear")178 179        self.expect(180            "command script list", matching=False, substrs=["targetname", "longwait"]181        )182 183        self.expect(184            "command script add -f foobar frame",185            error=True,186            substrs=["cannot add command"],187        )188 189        # http://llvm.org/bugs/show_bug.cgi?id=11569190        # LLDBSwigPythonCallCommand crashes when a command script returns an191        # object192        self.runCmd("command script add -f bug11569 bug11569")193        # This should not crash.194        self.runCmd("bug11569", check=False)195 196        # Make sure that a reference to a non-existent class raises an error:197        bad_class_name = "LLDBNoSuchModule.LLDBNoSuchClass"198        self.expect(199            "command script add wont-work --class {0}".format(bad_class_name),200            error=True,201            substrs=[bad_class_name],202        )203 204    def test_persistence(self):205        """206        Ensure that function arguments meaningfully persist (and do not crash!)207        even after the function terminates.208        """209        self.runCmd("command script import persistence.py")210        self.runCmd("command script add -f persistence.save_debugger save_debugger")211        self.expect("save_debugger", substrs=[str(self.dbg)])212 213        # After the command completes, the debugger object should still be214        # valid.215        self.expect("script str(persistence.debugger_copy)", substrs=[str(self.dbg)])216        # The result object will be replaced by an empty result object (in the217        # "Started" state).218        self.expect("script str(persistence.result_copy)", substrs=["Started"])219 220    def test_interactive(self):221        """222        Test that we can add multiple lines interactively.223        """224        interp = self.dbg.GetCommandInterpreter()225        cmd_file = self.getSourcePath("cmd_file.lldb")226        result = lldb.SBCommandReturnObject()227        interp.HandleCommand(f"command source {cmd_file}", result)228        self.assertCommandReturn(result, "Sourcing the command should cause no errors.")229        self.assertTrue(interp.UserCommandExists("my_cmd"), "Command defined.")230        interp.HandleCommand("my_cmd", result)231        self.assertCommandReturn(result, "Running the command succeeds")232        self.assertIn("My Command Result", result.GetOutput(), "Command was correct")233