reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
"""
Test lldb Python commands.
"""

from __future__ import print_function

import sys
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *


class CmdPythonTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)
    NO_DEBUG_INFO_TESTCASE = True

    def test(self):
        self.build()
        self.pycmd_tests()

    def pycmd_tests(self):
        self.runCmd("command source py_import")

        # Test a bunch of different kinds of python callables with
        # both 4 and 5 positional arguments.
        self.expect("foobar", substrs=["All good"])
        self.expect("foobar4", substrs=["All good"])
        self.expect("vfoobar", substrs=["All good"])
        self.expect("v5foobar", substrs=["All good"])
        self.expect("sfoobar", substrs=["All good"])
        self.expect("cfoobar", substrs=["All good"])
        self.expect("ifoobar", substrs=["All good"])
        self.expect("sfoobar4", substrs=["All good"])
        self.expect("cfoobar4", substrs=["All good"])
        self.expect("ifoobar4", substrs=["All good"])
        self.expect("ofoobar", substrs=["All good"])
        self.expect("ofoobar4", substrs=["All good"])

        # Verify command that specifies eCommandRequiresTarget returns failure
        # without a target.
        self.expect('targetname',
                    substrs=['a.out'], matching=False, error=True)

        exe = self.getBuildArtifact("a.out")
        self.expect("file " + exe,
                    patterns=["Current executable set to .*a.out"])

        self.expect('targetname',
                    substrs=['a.out'], matching=True, error=False)

        # This is the function to remove the custom commands in order to have a
        # clean slate for the next test case.
        def cleanup():
            self.runCmd('command script delete welcome', check=False)
            self.runCmd('command script delete targetname', check=False)
            self.runCmd('command script delete longwait', check=False)
            self.runCmd('command script delete mysto', check=False)
            self.runCmd('command script delete tell_sync', check=False)
            self.runCmd('command script delete tell_async', check=False)
            self.runCmd('command script delete tell_curr', check=False)
            self.runCmd('command script delete bug11569', check=False)
            self.runCmd('command script delete takes_exe_ctx', check=False)
            self.runCmd('command script delete decorated', check=False)

        # Execute the cleanup function during test case tear down.
        self.addTearDownHook(cleanup)

        # Interact with debugger in synchronous mode
        self.setAsync(False)

        # We don't want to display the stdout if not in TraceOn() mode.
        if not self.TraceOn():
            self.HideStdout()

        self.expect('welcome Enrico',
                    substrs=['Hello Enrico, welcome to LLDB'])

        self.expect("help welcome",
                    substrs=['Just a docstring for welcome_impl',
                             'A command that says hello to LLDB users'])

        decorated_commands = ["decorated" + str(n) for n in range(1, 5)]
        for name in decorated_commands:
            self.expect(name, substrs=["hello from " + name])
            self.expect("help " + name,
                        substrs=["Python command defined by @lldb.command"])

        self.expect("help",
                    substrs=['For more information run',
                             'welcome'] + decorated_commands)

        self.expect("help -a",
                    substrs=['For more information run',
                             'welcome'] + decorated_commands)

        self.expect("help -u", matching=False,
                    substrs=['For more information run'])

        self.runCmd("command script delete welcome")

        self.expect('welcome Enrico', matching=False, error=True,
                    substrs=['Hello Enrico, welcome to LLDB'])

        self.expect('targetname fail', error=True,
                    substrs=['a test for error in command'])

        self.expect('command script list',
                    substrs=['targetname',
                             'For more information run'])

        self.expect("help targetname",
                    substrs=['Expects', '\'raw\'', 'input',
                             'help', 'raw-input'])

        self.expect("longwait",
                    substrs=['Done; if you saw the delays I am doing OK'])

        self.runCmd("b main")
        self.runCmd("run")
        self.runCmd("mysto 3")
        self.expect("frame variable array",
                    substrs=['[0] = 79630', '[1] = 388785018', '[2] = 0'])
        self.runCmd("mysto 3")
        self.expect("frame variable array",
                    substrs=['[0] = 79630', '[4] = 388785018', '[5] = 0'])

# we cannot use the stepover command to check for async execution mode since LLDB
# seems to get confused when events start to queue up
        self.expect("tell_sync",
                    substrs=['running sync'])
        self.expect("tell_async",
                    substrs=['running async'])
        self.expect("tell_curr",
                    substrs=['I am running sync'])

# check that the execution context is passed in to commands that ask for it
        self.expect("takes_exe_ctx", substrs=["a.out"])

        # Test that a python command can redefine itself
        self.expect('command script add -f foobar welcome -h "just some help"')

        self.runCmd("command script clear")

        # Test that re-defining an existing command works
        self.runCmd(
            'command script add my_command --class welcome.WelcomeCommand')
        self.expect('my_command Blah', substrs=['Hello Blah, welcome to LLDB'])

        self.runCmd(
            'command script add my_command --class welcome.TargetnameCommand')
        self.expect('my_command', substrs=['a.out'])

        self.runCmd("command script clear")

        self.expect('command script list', matching=False,
                    substrs=['targetname',
                             'longwait'])

        self.expect('command script add -f foobar frame', error=True,
                    substrs=['cannot add command'])

        # http://llvm.org/bugs/show_bug.cgi?id=11569
        # LLDBSwigPythonCallCommand crashes when a command script returns an
        # object
        self.runCmd('command script add -f bug11569 bug11569')
        # This should not crash.
        self.runCmd('bug11569', check=False)