Debugging with GDB: GDB/MI Commands In Python

Next: Parameters In Python, Previous: CLI Commands In Python, Up: Python API [Contents][Index]

#### 23.3.2.21 GDB/MI Commands In Python

It is possible to add GDB/MI (see GDB/MI) commands implemented in Python. A GDB/MI command is implemented using an instance of the `gdb.MICommand` class, most commonly using a subclass.

Function: MICommand.__init__ (name)

  The object initializer for `MICommand` registers the new command with GDB. This initializer is normally invoked from the subclass’ own `__init__` method.

  name is the name of the command. It must be a valid name of a GDB/MI command, and in particular must start with a hyphen (`-`). Reusing the name of a built-in GDB/MI is not allowed, and a `RuntimeError` will be raised. Using the name of an GDB/MI command previously defined in Python is allowed, the previous command will be replaced with the new command.

Function: MICommand.invoke (arguments)

  This method is called by GDB when the new MI command is invoked.

  arguments is a list of strings. Note, that `--thread` and `--frame` arguments are handled by GDB itself therefore they do not show up in `arguments`.

  If this method raises an exception, then it is turned into a GDB/MI `^error` response. Only `gdb.GdbError` exceptions (or its sub-classes) should be used for reporting errors to users, any other exception type is treated as a failure of the `invoke` method, and the exception will be printed to the error stream according to the `set python print-stack` setting (see `set python print-stack`).

  If this method returns `None`, then the GDB/MI command will return a `^done` response with no additional values.

  Otherwise, the return value must be a dictionary, which is converted to a GDB/MI result-record (see GDB/MI Output Syntax). The keys of this dictionary must be strings, and are used as variable names in the result-record, these strings must comply with the naming rules detailed below. The values of this dictionary are recursively handled as follows:

  - If the value is Python sequence or iterator, it is converted to GDB/MI list with elements converted recursively.
  - If the value is Python dictionary, it is converted to GDB/MI tuple. Keys in that dictionary must be strings, which comply with the variable naming rules detailed below. Values are converted recursively.
  - Otherwise, value is first converted to a Python string using `str ()` and then converted to GDB/MI const.

  The strings used for variable names in the GDB/MI output must follow the following rules; the string must be at least one character long, the first character must be in the set `[a-zA-Z]`, while every subsequent character must be in the set `[-_a-zA-Z0-9]`.

An instance of `MICommand` has the following attributes:

Variable: MICommand.name

  A string, the name of this GDB/MI command, as was passed to the `__init__` method. This attribute is read-only.

Variable: MICommand.installed

  A boolean value indicating if this command is installed ready for a user to call from the command line. Commands are automatically installed when they are instantiated, after which this attribute will be `True`.

  If later, a new command is created with the same name, then the original command will become uninstalled, and this attribute will be `False`.

  This attribute is read-write, setting this attribute to `False` will uninstall the command, removing it from the set of available commands. Setting this attribute to `True` will install the command for use. If there is already a Python command with this name installed, the currently installed command will be uninstalled, and this command installed in its place.

The following code snippet shows how a two trivial MI command can be implemented in Python:

    class MIEcho(gdb.MICommand):
        """Echo arguments passed to the command."""

        def __init__(self, name, mode):
            self._mode = mode
            super(MIEcho, self).__init__(name)

        def invoke(self, argv):
            if self._mode == 'dict':
                return { 'dict': { 'argv' : argv } }
            elif self._mode == 'list':
                return { 'list': argv }
            else:
                return { 'string': ", ".join(argv) }

    MIEcho("-echo-dict", "dict")
    MIEcho("-echo-list", "list")
    MIEcho("-echo-string", "string")

The last three lines instantiate the class three times, creating three new GDB/MI commands `-echo-dict`, `-echo-list`, and `-echo-string`. Each time a subclass of `gdb.MICommand` is instantiated, the new command is automatically registered with GDB.

Depending on how the Python code is read into GDB, you may need to import the `gdb` module explicitly.

The following example shows a GDB session in which the above commands have been added:

    (gdb)
    -echo-dict abc def ghi
    ^done,dict={argv=["abc","def","ghi"]}
    (gdb)
    -echo-list abc def ghi
    ^done,list=["abc","def","ghi"]
    (gdb)
    -echo-string abc def ghi
    ^done,string="abc, def, ghi"
    (gdb)

Next: Parameters In Python, Previous: CLI Commands In Python, Up: Python API [Contents][Index]