scripts: gdb: Added some useful GDB scripts to test.py --gdb

These just invoke the existing dbg*.py python scripts, but allow quick
references to variables in the debugginged process:

  (gdb) dbgflags o file->b.o.flags
  LFS3_O_RDWR    0x00000002  Open a file as read and write
  LFS3_o_REG     0x10000000  Type = regular-file
  LFS3_o_UNSYNC  0x01000000  File's metadata does not match disk

Quite neat and useful!

This works by injecting dbg.gdb.py via gdb -x, which includes the
necessary python hooks to add these commands to gdb. This can be
overridden/extended with test.py/bench.py's --gdb-script flag.

Currently limited to scripts that seem the most useful for process
internals:

- dbgerr - Decode littlefs error codes
- dbgflags - Decode littlefs flags
- dbgtag - Decode littlefs tags
This commit is contained in:
Christopher Haster
2025-07-04 12:35:49 -05:00
parent b700c8c819
commit 0b804c092b
3 changed files with 140 additions and 9 deletions

97
scripts/dbg.gdb.py Normal file
View File

@@ -0,0 +1,97 @@
#
# hooks for gdb:
# (gdb) source ./scripts/dbg.gdb.py
#
#
# dbgerr
class DbgErr(gdb.Command):
"""Decode littlefs error codes. See -h/--help for more info."""
def __init__(self):
super().__init__("dbgerr",
gdb.COMMAND_DATA,
gdb.COMPLETE_EXPRESSION)
def invoke(self, args, *_):
args = args.split()
# find nonflags
nonflags = []
for i, a in enumerate(args):
if not a.startswith('-'):
nonflags.append(i)
# parse and eval
for i, n in enumerate(nonflags):
try:
args[n] = '%d' % gdb.parse_and_eval(args[n])
except gdb.error as e:
raise gdb.GdbError(e)
# execute
gdb.execute(' '.join(['!./scripts/dbgerr.py'] + args))
DbgErr()
# dbgflags
class DbgFlags(gdb.Command):
"""Decode littlefs flags. See -h/--help for more info."""
def __init__(self):
super().__init__("dbgflags",
gdb.COMMAND_DATA,
gdb.COMPLETE_EXPRESSION)
def invoke(self, args, *_):
args = args.split()
# hack, but don't eval if -l or --list specified
if '-l' not in args and '--list' not in args:
# find nonflags
nonflags = []
for i, a in enumerate(args):
if not a.startswith('-'):
nonflags.append(i)
# parse and eval
for i, n in enumerate(nonflags):
# dbgflags is special in that first arg may be prefix
if i > 0 or len(nonflags) <= 1:
try:
args[n] = '%d' % gdb.parse_and_eval(args[n])
except gdb.error as e:
raise gdb.GdbError(e)
# execute
gdb.execute(' '.join(['!./scripts/dbgflags.py'] + args))
DbgFlags()
# dbgtag
class DbgTag(gdb.Command):
"""Decode littlefs tags. See -h/--help for more info."""
def __init__(self):
super().__init__("dbgtag",
gdb.COMMAND_DATA,
gdb.COMPLETE_EXPRESSION)
def invoke(self, args, *_):
args = args.split()
# find nonflags
nonflags = []
for i, a in enumerate(args):
if not a.startswith('-'):
nonflags.append(i)
# parse and eval
for i, n in enumerate(nonflags):
try:
args[n] = '%d' % gdb.parse_and_eval(args[n])
except gdb.error as e:
raise gdb.GdbError(e)
# execute
gdb.execute(' '.join(['!./scripts/dbgtag.py'] + args))
DbgTag()