Skip to content

Develop custom commands

Andrea Cardaci edited this page Dec 28, 2021 · 1 revision

Personal configuration files can also be used to introduce custom GDB commands. This can be achieved by using the define command, and they can even contain Python code. For example, consider the following command that prints the Python version:

define get-python-version
python
import sys
print(sys.version)
end
end

Optionally, it is possible to add some documentation using the document command:

document get-python-version
Print the version of Python embedded within this GDB.
end

The above intruduces the get-python-version command that can be used as follows:

>>> help get-python-version
Print the version of Python embedded within this GDB.
>>> get-python-version
3.10.1 (main, Dec  6 2021, 23:20:29) [Clang 13.0.0 (clang-1300.0.29.3)]

The define command is more than enough for simple tasks, but for more complex use cases it is better to rely on Python completely by extending the gdb.Command class. For example the following is equivalent, just put in a Python file:

class GetPythonVersionCommand(gdb.Command):
    '''This will appear in the GDB help system.'''

    def __init__(self):
        gdb.Command.__init__(self, 'get-python-version', gdb.COMMAND_USER)

    def invoke(self, arg, from_tty):
        print(sys.version)

GetPythonVersionCommand()

This mechanism also allows to add third-party commands to the dashboard itself, if really needed. Remember that by convention, the dashboard subcommands starts with a - to distinguish between commands and modules. See for example this custom command that lists the available modules (yet there is already dashboard -layout for that):

class FancyLayoutCommand(gdb.Command):
    '''List the available modules in a fancy way.'''

    def __init__(self, dashboard):
        gdb.Command.__init__(self, 'dashboard -fancy-layout', gdb.COMMAND_USER)
        self.dashboard = dashboard

    def invoke(self, arg, from_tty):
        for index, module in enumerate(self.dashboard.modules, start=1):
            if module.enabled:
                brief, _, _ = module.doc.partition('\n')
                print('{}) {}\n\t{}'.format(index, module.name, brief))

FancyLayoutCommand(dashboard)