2 Test lldb Python commands.
8 from lldbsuite
.test
.decorators
import *
9 from lldbsuite
.test
.lldbtest
import *
12 class CmdPythonTestCase(TestBase
):
13 NO_DEBUG_INFO_TESTCASE
= True
19 def pycmd_tests(self
):
20 self
.runCmd("command source py_import")
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.")
27 # Test a bunch of different kinds of python callables with
28 # 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"])
42 # Verify command that specifies eCommandRequiresTarget returns failure
44 self
.expect("targetname", substrs
=["a.out"], matching
=False, error
=True)
46 exe
= self
.getBuildArtifact("a.out")
47 self
.expect("file " + exe
, patterns
=["Current executable set to .*a.out"])
49 self
.expect("targetname", substrs
=["a.out"], matching
=True, error
=False)
51 # This is the function to remove the custom commands in order to have a
52 # clean slate for the next test case.
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)
65 # Execute the cleanup function during test case tear down.
66 self
.addTearDownHook(cleanup
)
68 # Interact with debugger in synchronous mode
71 # We don't want to display the stdout if not in TraceOn() mode.
72 if not self
.TraceOn():
75 self
.expect("welcome Enrico", substrs
=["Hello Enrico, welcome to LLDB"])
80 "Just a docstring for welcome_impl",
81 "A command that says hello to LLDB users",
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
])
89 "help " + name
, substrs
=["Python command defined by @lldb.command"]
94 substrs
=["For more information run"] + decorated_commands
+ ["welcome"],
99 substrs
=["For more information run"] + decorated_commands
+ ["welcome"],
102 self
.expect("help -u", matching
=False, substrs
=["For more information run"])
104 self
.runCmd("command script delete welcome")
110 substrs
=["Hello Enrico, welcome to LLDB"],
114 "targetname fail", error
=True, substrs
=["a test for error in command"]
118 "command script list", substrs
=["targetname", "For more information run"]
123 substrs
=["Expects", "'raw'", "input", "help", "raw-input"],
126 self
.expect("longwait", substrs
=["Done; if you saw the delays I am doing OK"])
128 self
.runCmd("break set -f main.cpp -l 48")
130 self
.runCmd("mysto 3")
132 "frame variable array",
133 substrs
=["[0] = 79630", "[1] = 388785018", "[2] = 0"],
135 self
.runCmd("mysto 3")
137 "frame variable array",
138 substrs
=["[0] = 79630", "[4] = 388785018", "[5] = 0"],
141 # we cannot use the stepover command to check for async execution mode since LLDB
142 # seems to get confused when events start to queue up
143 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"])
147 # check that the execution context is passed in to commands that ask for it
148 self
.expect("takes_exe_ctx", substrs
=["a.out"])
150 # Test that a python command can redefine itself
151 self
.expect('command script add -f foobar welcome -h "just some help"')
153 self
.runCmd("command script clear")
155 # Test that re-defining an existing command works
156 self
.runCmd("command script add my_command --class welcome.WelcomeCommand")
157 self
.expect("my_command Blah", substrs
=["Hello Blah, welcome to LLDB"])
160 "command script add my_command -o --class welcome.TargetnameCommand"
162 self
.expect("my_command", substrs
=["a.out"])
164 # Test that without --overwrite we are not allowed to redefine the command.
166 "command script add my_command --class welcome.TargetnameCommand",
169 'user command "my_command" already exists and force replace was'
170 " not set by --overwrite or 'settings set"
171 " interpreter.require-overwrite false'"
177 self
.runCmd("command script clear")
180 "command script list", matching
=False, substrs
=["targetname", "longwait"]
184 "command script add -f foobar frame",
186 substrs
=["cannot add command"],
189 # http://llvm.org/bugs/show_bug.cgi?id=11569
190 # LLDBSwigPythonCallCommand crashes when a command script returns an
192 self
.runCmd("command script add -f bug11569 bug11569")
193 # This should not crash.
194 self
.runCmd("bug11569", check
=False)
196 # Make sure that a reference to a non-existent class raises an error:
197 bad_class_name
= "LLDBNoSuchModule.LLDBNoSuchClass"
199 "command script add wont-work --class {0}".format(bad_class_name
),
201 substrs
=[bad_class_name
],
204 def test_persistence(self
):
206 Ensure that function arguments meaningfully persist (and do not crash!)
207 even after the function terminates.
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
)])
213 # After the command completes, the debugger object should still be
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 the
218 self
.expect("script str(persistence.result_copy)", substrs
=["Started"])
220 def test_interactive(self
):
222 Test that we can add multiple lines interactively.
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")