This Python package provides functions and classes to support implementations of custom LLDB commands.
The command line parsing, as well as the help text for your command are provided automatically, thanks to argparse module.
This repository is meant to be a submodule of lldb-bundle, look there for installation instructions.
You also have an option to clone this repository and add the following line
into your ~/.lldbinit
file:
command script import <path-to-repository>/lldb_script_utils
To create an LLDB command with this package, you need to subclass the
LLDBArgumentParser.Command
and implement its create_args_parser
method:
import lldb
from lldb_script_utils import debugger_utils
from lldb_script_utils import lldb_commands
def __lldb_init_module(debugger: lldb.SBDebugger, _: dict) -> None:
TestCommand1.lldb_init_class(debugger)
class TestCommand1(lldb_commands.LLDBCommand):
"""A test command with an argument."""
NAME = 'testCommand1'
HELP = 'Help on testCommand1.'
@classmethod
def lldb_init_class(cls, debugger: lldb.SBDebugger) -> None:
debugger_utils.handle_command_script_add(debugger, cls.NAME, cls)
def create_args_parser(self, debugger: lldb.SBDebugger,
bindings: dict) -> lldb_commands.LLDBArgumentParser:
parser = lldb_commands.LLDBArgumentParser(self.NAME, self.HELP)
parser.add_argument('magic_number', type=int, help='Help on magic.')
parser.set_command_handler(self._on_command1)
return parser
def _on_command1(self, magic_number: int, **_):
print(f'The answer is {magic_number}')
The example above also demonstrates how to register your command with LLDB.
Assuming the file is saved as examples/test_command1.py, you can import it into LLDB, and run:
$ lldb
(lldb) command script import examples/test_command1.py
(lldb) help testCommand1
Help on testCommand1. Expects 'raw' input (see 'help raw-input'.)
Syntax: testCommand1
usage: testCommand1 magic_number
Positional arguments:
magic_number Help on magic.
(lldb) testCommand1
usage: testCommand1 magic_number
testCommand1: error: the following arguments are required: magic_number
(lldb) testCommand1 42
The answer is 42
You can add positional arguments, optional arguments (options), and subcommands to
your command. The arguments and options are added as described in the
documentation for the
argparse
module. To add subcommands, use add_subcommands
method as follows:
import lldb
import argparse
from typing import Type
from lldb_script_utils import lldb_commands
from lldb_script_utils import debugger_utils
def __lldb_init_module(debugger: lldb.SBDebugger, _: dict) -> None:
# pylint: disable=invalid-name
TestCommand2.lldb_init_class(debugger)
class TestCommand2(lldb_commands.LLDBCommand):
"""A test command with subcommands."""
NAME = 'testCommand2'
HELP = 'Help on testCommand2.'
@classmethod
def lldb_init_class(cls, debugger: lldb.SBDebugger) -> None:
debugger_utils.handle_command_script_add(debugger, cls.NAME, cls)
def create_args_parser(self, debugger: lldb.SBDebugger,
bindings: dict) -> lldb_commands.LLDBArgumentParser:
parser = lldb_commands.LLDBArgumentParser(self.NAME, self.HELP)
parser.add_subcommands(
(self.Subcommand1, self._on_subcommand1),
(self.Subcommand2, self._on_subcommand2),
)
return parser
class Subcommand1(lldb_commands.LLDBSubcommand):
"""The first subcommand."""
NAME = 'subcommand1'
HELP = 'Help on subcommand1.'
@classmethod
def create_args_subparser(
cls, add_subparser: Type[argparse.ArgumentParser]
) -> argparse.ArgumentParser:
subparser = add_subparser(cls.NAME, cls.HELP)
return subparser
def _on_subcommand1(self, **_):
print('Hello from subcommand1')
Assuming the file is saved as examples/test_command2.py, you can import and run it as follows:
$ lldb
(lldb) command script import examples/test_command2.py
(lldb) help testCommand2
Help on testCommand2. Expects 'raw' input (see 'help raw-input'.)
Syntax: testCommand2
usage: testCommand2 <subcommand> ...
The following subcommands are supported:
<subcommand>
subcommand1
Help on subcommand1.
subcommand2
Help on subcommand2.
For more help on any particular subcommand, type 'testCommand2 <subcommand> --help'.
(lldb) testCommand2 subcommand1
Hello from subcommand1
Feel free to file an issue, or send a pull request.
Before making your changes, you need to establish a development environment. As this repository is meant to be a submodule of lldb-bundle, look there for creating the Python virtual environment suitable for developing with LLDB.
Once you activated the virtual environment, run:
make init
to install the required development tools.
Use your editor or IDE to make your changes. Add relevant tests. To prepare for a submission, run:
make format
make lint
make test
Fix lint issues and test failures.
Repeat until everything is OK, then open a pull request.
Thanks!