199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest lldb Python commands. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprecht 699451b44SJordan Rupprechtimport sys 799451b44SJordan Rupprechtimport lldb 899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprecht 1299451b44SJordan Rupprechtclass CmdPythonTestCase(TestBase): 1399451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1499451b44SJordan Rupprecht 1599451b44SJordan Rupprecht def test(self): 1699451b44SJordan Rupprecht self.build() 1799451b44SJordan Rupprecht self.pycmd_tests() 1899451b44SJordan Rupprecht 1999451b44SJordan Rupprecht def pycmd_tests(self): 2099451b44SJordan Rupprecht self.runCmd("command source py_import") 2199451b44SJordan Rupprecht 2299451b44SJordan Rupprecht # Test a bunch of different kinds of python callables with 2399451b44SJordan Rupprecht # both 4 and 5 positional arguments. 2499451b44SJordan Rupprecht self.expect("foobar", substrs=["All good"]) 2599451b44SJordan Rupprecht self.expect("foobar4", substrs=["All good"]) 2699451b44SJordan Rupprecht self.expect("vfoobar", substrs=["All good"]) 2799451b44SJordan Rupprecht self.expect("v5foobar", substrs=["All good"]) 2899451b44SJordan Rupprecht self.expect("sfoobar", substrs=["All good"]) 2999451b44SJordan Rupprecht self.expect("cfoobar", substrs=["All good"]) 3099451b44SJordan Rupprecht self.expect("ifoobar", substrs=["All good"]) 3199451b44SJordan Rupprecht self.expect("sfoobar4", substrs=["All good"]) 3299451b44SJordan Rupprecht self.expect("cfoobar4", substrs=["All good"]) 3399451b44SJordan Rupprecht self.expect("ifoobar4", substrs=["All good"]) 3499451b44SJordan Rupprecht self.expect("ofoobar", substrs=["All good"]) 3599451b44SJordan Rupprecht self.expect("ofoobar4", substrs=["All good"]) 3699451b44SJordan Rupprecht 3799451b44SJordan Rupprecht # Verify command that specifies eCommandRequiresTarget returns failure 3899451b44SJordan Rupprecht # without a target. 3999451b44SJordan Rupprecht self.expect('targetname', 4099451b44SJordan Rupprecht substrs=['a.out'], matching=False, error=True) 4199451b44SJordan Rupprecht 4299451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 4399451b44SJordan Rupprecht self.expect("file " + exe, 4499451b44SJordan Rupprecht patterns=["Current executable set to .*a.out"]) 4599451b44SJordan Rupprecht 4699451b44SJordan Rupprecht self.expect('targetname', 4799451b44SJordan Rupprecht substrs=['a.out'], matching=True, error=False) 4899451b44SJordan Rupprecht 4999451b44SJordan Rupprecht # This is the function to remove the custom commands in order to have a 5099451b44SJordan Rupprecht # clean slate for the next test case. 5199451b44SJordan Rupprecht def cleanup(): 5299451b44SJordan Rupprecht self.runCmd('command script delete welcome', check=False) 5399451b44SJordan Rupprecht self.runCmd('command script delete targetname', check=False) 5499451b44SJordan Rupprecht self.runCmd('command script delete longwait', check=False) 5599451b44SJordan Rupprecht self.runCmd('command script delete mysto', check=False) 5699451b44SJordan Rupprecht self.runCmd('command script delete tell_sync', check=False) 5799451b44SJordan Rupprecht self.runCmd('command script delete tell_async', check=False) 5899451b44SJordan Rupprecht self.runCmd('command script delete tell_curr', check=False) 5999451b44SJordan Rupprecht self.runCmd('command script delete bug11569', check=False) 6099451b44SJordan Rupprecht self.runCmd('command script delete takes_exe_ctx', check=False) 6199451b44SJordan Rupprecht self.runCmd('command script delete decorated', check=False) 6299451b44SJordan Rupprecht 6399451b44SJordan Rupprecht # Execute the cleanup function during test case tear down. 6499451b44SJordan Rupprecht self.addTearDownHook(cleanup) 6599451b44SJordan Rupprecht 6699451b44SJordan Rupprecht # Interact with debugger in synchronous mode 6799451b44SJordan Rupprecht self.setAsync(False) 6899451b44SJordan Rupprecht 6999451b44SJordan Rupprecht # We don't want to display the stdout if not in TraceOn() mode. 7099451b44SJordan Rupprecht if not self.TraceOn(): 7199451b44SJordan Rupprecht self.HideStdout() 7299451b44SJordan Rupprecht 7399451b44SJordan Rupprecht self.expect('welcome Enrico', 7499451b44SJordan Rupprecht substrs=['Hello Enrico, welcome to LLDB']) 7599451b44SJordan Rupprecht 7699451b44SJordan Rupprecht self.expect("help welcome", 7799451b44SJordan Rupprecht substrs=['Just a docstring for welcome_impl', 7899451b44SJordan Rupprecht 'A command that says hello to LLDB users']) 7999451b44SJordan Rupprecht 8099451b44SJordan Rupprecht decorated_commands = ["decorated" + str(n) for n in range(1, 5)] 8199451b44SJordan Rupprecht for name in decorated_commands: 8299451b44SJordan Rupprecht self.expect(name, substrs=["hello from " + name]) 8399451b44SJordan Rupprecht self.expect("help " + name, 8499451b44SJordan Rupprecht substrs=["Python command defined by @lldb.command"]) 8599451b44SJordan Rupprecht 8699451b44SJordan Rupprecht self.expect("help", 8799451b44SJordan Rupprecht substrs=['For more information run'] 8899451b44SJordan Rupprecht + decorated_commands + ['welcome']) 8999451b44SJordan Rupprecht 9099451b44SJordan Rupprecht self.expect("help -a", 9199451b44SJordan Rupprecht substrs=['For more information run'] 9299451b44SJordan Rupprecht + decorated_commands + ['welcome']) 9399451b44SJordan Rupprecht 9499451b44SJordan Rupprecht self.expect("help -u", matching=False, 9599451b44SJordan Rupprecht substrs=['For more information run']) 9699451b44SJordan Rupprecht 9799451b44SJordan Rupprecht self.runCmd("command script delete welcome") 9899451b44SJordan Rupprecht 9999451b44SJordan Rupprecht self.expect('welcome Enrico', matching=False, error=True, 10099451b44SJordan Rupprecht substrs=['Hello Enrico, welcome to LLDB']) 10199451b44SJordan Rupprecht 10299451b44SJordan Rupprecht self.expect('targetname fail', error=True, 10399451b44SJordan Rupprecht substrs=['a test for error in command']) 10499451b44SJordan Rupprecht 10599451b44SJordan Rupprecht self.expect('command script list', 10699451b44SJordan Rupprecht substrs=['targetname', 10799451b44SJordan Rupprecht 'For more information run']) 10899451b44SJordan Rupprecht 10999451b44SJordan Rupprecht self.expect("help targetname", 11099451b44SJordan Rupprecht substrs=['Expects', '\'raw\'', 'input', 11199451b44SJordan Rupprecht 'help', 'raw-input']) 11299451b44SJordan Rupprecht 11399451b44SJordan Rupprecht self.expect("longwait", 11499451b44SJordan Rupprecht substrs=['Done; if you saw the delays I am doing OK']) 11599451b44SJordan Rupprecht 116*dd01d9aaSMuhammad Omair Javaid self.runCmd("break set -f main.cpp -l 48") 11799451b44SJordan Rupprecht self.runCmd("run") 11899451b44SJordan Rupprecht self.runCmd("mysto 3") 11999451b44SJordan Rupprecht self.expect("frame variable array", 12099451b44SJordan Rupprecht substrs=['[0] = 79630', '[1] = 388785018', '[2] = 0']) 12199451b44SJordan Rupprecht self.runCmd("mysto 3") 12299451b44SJordan Rupprecht self.expect("frame variable array", 12399451b44SJordan Rupprecht substrs=['[0] = 79630', '[4] = 388785018', '[5] = 0']) 12499451b44SJordan Rupprecht 12599451b44SJordan Rupprecht# we cannot use the stepover command to check for async execution mode since LLDB 12699451b44SJordan Rupprecht# seems to get confused when events start to queue up 12799451b44SJordan Rupprecht self.expect("tell_sync", 12899451b44SJordan Rupprecht substrs=['running sync']) 12999451b44SJordan Rupprecht self.expect("tell_async", 13099451b44SJordan Rupprecht substrs=['running async']) 13199451b44SJordan Rupprecht self.expect("tell_curr", 13299451b44SJordan Rupprecht substrs=['I am running sync']) 13399451b44SJordan Rupprecht 13499451b44SJordan Rupprecht# check that the execution context is passed in to commands that ask for it 13599451b44SJordan Rupprecht self.expect("takes_exe_ctx", substrs=["a.out"]) 13699451b44SJordan Rupprecht 13799451b44SJordan Rupprecht # Test that a python command can redefine itself 13899451b44SJordan Rupprecht self.expect('command script add -f foobar welcome -h "just some help"') 13999451b44SJordan Rupprecht 14099451b44SJordan Rupprecht self.runCmd("command script clear") 14199451b44SJordan Rupprecht 14299451b44SJordan Rupprecht # Test that re-defining an existing command works 14399451b44SJordan Rupprecht self.runCmd( 14499451b44SJordan Rupprecht 'command script add my_command --class welcome.WelcomeCommand') 14599451b44SJordan Rupprecht self.expect('my_command Blah', substrs=['Hello Blah, welcome to LLDB']) 14699451b44SJordan Rupprecht 14799451b44SJordan Rupprecht self.runCmd( 148c5011aedSJim Ingham 'command script add my_command -o --class welcome.TargetnameCommand') 14999451b44SJordan Rupprecht self.expect('my_command', substrs=['a.out']) 15099451b44SJordan Rupprecht 15199451b44SJordan Rupprecht self.runCmd("command script clear") 15299451b44SJordan Rupprecht 15399451b44SJordan Rupprecht self.expect('command script list', matching=False, 15499451b44SJordan Rupprecht substrs=['targetname', 15599451b44SJordan Rupprecht 'longwait']) 15699451b44SJordan Rupprecht 15799451b44SJordan Rupprecht self.expect('command script add -f foobar frame', error=True, 15899451b44SJordan Rupprecht substrs=['cannot add command']) 15999451b44SJordan Rupprecht 16099451b44SJordan Rupprecht # http://llvm.org/bugs/show_bug.cgi?id=11569 16199451b44SJordan Rupprecht # LLDBSwigPythonCallCommand crashes when a command script returns an 16299451b44SJordan Rupprecht # object 16399451b44SJordan Rupprecht self.runCmd('command script add -f bug11569 bug11569') 16499451b44SJordan Rupprecht # This should not crash. 16599451b44SJordan Rupprecht self.runCmd('bug11569', check=False) 1667406d236SPavel Labath 1677406d236SPavel Labath def test_persistence(self): 1680a07c966SPavel Labath """ 1690a07c966SPavel Labath Ensure that function arguments meaningfully persist (and do not crash!) 1700a07c966SPavel Labath even after the function terminates. 1710a07c966SPavel Labath """ 1727406d236SPavel Labath self.runCmd("command script import persistence.py") 1737406d236SPavel Labath self.runCmd("command script add -f persistence.save_debugger save_debugger") 1747406d236SPavel Labath self.expect("save_debugger", substrs=[str(self.dbg)]) 1750a07c966SPavel Labath 1760a07c966SPavel Labath # After the command completes, the debugger object should still be 1770a07c966SPavel Labath # valid. 1787406d236SPavel Labath self.expect("script str(persistence.debugger_copy)", substrs=[str(self.dbg)]) 1790a07c966SPavel Labath # The result object will be replaced by an empty result object (in the 1800a07c966SPavel Labath # "Started" state). 1810a07c966SPavel Labath self.expect("script str(persistence.result_copy)", substrs=["Started"]) 182