mirror of https://github.com/pwndbg/pwndbg
Fix missing help strings for Pwndbg commands in GDB (#2351)
* Fix missing help strings in GDB with the `help` command * Add a test that checks whether the `help` command in GDB works for Pwndbg commands
This commit is contained in:
parent
12d8c3960f
commit
8b24e27152
|
@ -90,11 +90,13 @@ class Command:
|
|||
is_alias: bool = False,
|
||||
aliases: List[str] = [],
|
||||
category: CommandCategory = CommandCategory.MISC,
|
||||
doc: str | None = None,
|
||||
) -> None:
|
||||
self.is_alias = is_alias
|
||||
self.aliases = aliases
|
||||
self.category = category
|
||||
self.shell = shell
|
||||
self.doc = doc
|
||||
|
||||
if command_name is None:
|
||||
command_name = function.__name__
|
||||
|
@ -102,7 +104,7 @@ class Command:
|
|||
def _handler(_debugger, arguments, is_interactive):
|
||||
self.invoke(arguments, is_interactive)
|
||||
|
||||
self.handle = pwndbg.dbg.add_command(command_name, _handler)
|
||||
self.handle = pwndbg.dbg.add_command(command_name, _handler, doc)
|
||||
self.function = function
|
||||
|
||||
if command_name in command_names:
|
||||
|
@ -547,7 +549,7 @@ class _ArgparsedCommand(Command):
|
|||
file = io.StringIO()
|
||||
self.parser.print_help(file)
|
||||
file.seek(0)
|
||||
self.__doc__ = file.read()
|
||||
doc = file.read()
|
||||
# Note: function.__doc__ is used in the `pwndbg [filter]` command display
|
||||
function.__doc__ = self.parser.description.strip()
|
||||
|
||||
|
@ -555,6 +557,7 @@ class _ArgparsedCommand(Command):
|
|||
super().__init__( # type: ignore[misc]
|
||||
function,
|
||||
command_name=command_name,
|
||||
doc=doc,
|
||||
*a,
|
||||
**kw,
|
||||
)
|
||||
|
|
|
@ -352,7 +352,7 @@ class Debugger:
|
|||
raise NotImplementedError()
|
||||
|
||||
def add_command(
|
||||
self, name: str, handler: Callable[[Debugger, str, bool], None]
|
||||
self, name: str, handler: Callable[[Debugger, str, bool], None], doc: str | None
|
||||
) -> CommandHandle:
|
||||
"""
|
||||
Adds a command with the given name to the debugger, that invokes the
|
||||
|
|
|
@ -129,9 +129,11 @@ class GDBCommand(gdb.Command):
|
|||
debugger: GDB,
|
||||
name: str,
|
||||
handler: Callable[[pwndbg.dbg_mod.Debugger, str, bool], None],
|
||||
doc: str | None,
|
||||
):
|
||||
self.debugger = debugger
|
||||
self.handler = handler
|
||||
self.__doc__ = doc
|
||||
super().__init__(name, gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION)
|
||||
|
||||
def invoke(self, args: str, from_tty: bool) -> None:
|
||||
|
@ -326,9 +328,12 @@ class GDB(pwndbg.dbg_mod.Debugger):
|
|||
|
||||
@override
|
||||
def add_command(
|
||||
self, name: str, handler: Callable[[pwndbg.dbg_mod.Debugger, str, bool], None]
|
||||
self,
|
||||
name: str,
|
||||
handler: Callable[[pwndbg.dbg_mod.Debugger, str, bool], None],
|
||||
doc: str | None,
|
||||
) -> pwndbg.dbg_mod.CommandHandle:
|
||||
command = GDBCommand(self, name, handler)
|
||||
command = GDBCommand(self, name, handler, doc)
|
||||
return GDBCommandHandle(command)
|
||||
|
||||
@override
|
||||
|
|
|
@ -260,7 +260,10 @@ class LLDB(pwndbg.dbg_mod.Debugger):
|
|||
|
||||
@override
|
||||
def add_command(
|
||||
self, command_name: str, handler: Callable[[pwndbg.dbg_mod.Debugger, str, bool], None]
|
||||
self,
|
||||
command_name: str,
|
||||
handler: Callable[[pwndbg.dbg_mod.Debugger, str, bool], None],
|
||||
doc: str | None,
|
||||
) -> pwndbg.dbg_mod.CommandHandle:
|
||||
debugger = self
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import gdb
|
||||
|
||||
from pwndbg import commands
|
||||
|
||||
|
||||
def test_command_help_strings(start_binary):
|
||||
"""
|
||||
Tests whether the `help` command works for Pwndbg commands. We go through
|
||||
every command and check whether the value of `help <command>` matches the
|
||||
help string we pass to the Debugger-agnostic API when it's being registered.
|
||||
"""
|
||||
|
||||
for command in commands.commands:
|
||||
help_str = gdb.execute(f"help {command.__name__}", from_tty=False, to_string=True)
|
||||
if command.doc is None:
|
||||
assert help_str.strip() == "This command is not documented."
|
||||
else:
|
||||
truth = [line.strip() for line in command.doc.splitlines() if len(line.strip()) > 0]
|
||||
gdb_out = [line.strip() for line in help_str.splitlines() if len(line.strip()) > 0]
|
||||
|
||||
# We check both of these cases since for some commands GDB will
|
||||
# output the list of aliases as the first line.
|
||||
assert truth == gdb_out or truth == gdb_out[1:]
|
Loading…
Reference in New Issue