mirror of
https://github.com/littlefs-project/littlefs.git
synced 2026-04-02 04:35:20 +00:00
I'm trying to avoid the inevitable conflict with -w/--word, which will probably become important when exploring non-32-bit filesystem configurations. Renaming this to -t/--wait still conflicts with -t/--tree and -t/--tiny, but as a debug-only flag, I think these are less important. Oh, and -t/--trace, but test.py/bench.py are already quite different in their flag naming (see -d/--disk vs -d/--diff). --- Renamed a few other flags while tweaking things: - -t/--tiny -> --tiny (dropped shortform) - -w/--word-bits -> -w/--word/--word-bits - -t/--tree -> -R/--tree/--rbyd/--tree-rbyd - -R/--tree-rbyd -> -Y/--rbyd-all/--tree-rbyd-all - -B/--tree-btree -> -B/--btree/--tree-btree After tinkering with it a bit, I think the -R/-Y/-B set of flags are a decent way to organize the tree renderers. At least --tree-rbyd-all does a better job of describing the difference between --tree-rbyd and --tree-rbyd-all.
137 lines
3.5 KiB
Python
137 lines
3.5 KiB
Python
#
|
|
# Hooks for gdb:
|
|
# (gdb) source ./scripts/dbg.gdb.py
|
|
#
|
|
#
|
|
|
|
import shlex
|
|
|
|
|
|
# split spaces but only outside of parens and quotes
|
|
def gdbsplit(v):
|
|
parens = 0
|
|
quote = None
|
|
escape = False
|
|
i_ = 0
|
|
for i in range(len(v)):
|
|
if v[i].isspace() and not parens and not quote:
|
|
v_ = v[i_:i].strip()
|
|
if v_:
|
|
yield v_
|
|
i_ = i+1
|
|
elif quote:
|
|
if escape:
|
|
escape = False
|
|
elif v[i] == quote:
|
|
quote = None
|
|
elif v[i] == '\\':
|
|
escape = True
|
|
elif v[i] in '\'"':
|
|
quote = v[i]
|
|
elif v[i] in '([{':
|
|
parens += 1
|
|
elif v[i] in '}])':
|
|
parens -= 1
|
|
v_ = v[i_:].strip()
|
|
if v_:
|
|
yield v_
|
|
|
|
# common wrapper for dbg scripts
|
|
#
|
|
# Note some tricks to help interact with bash and gdb:
|
|
#
|
|
# - Flags are passed as is (-h, -b4096, --trunk)
|
|
# - All non-flags are parsed as expressions (file->b.shrub.blocks[0])
|
|
# - String expressions may be useful for paths and stuff ("./disk")
|
|
#
|
|
class DbgCommand(gdb.Command):
|
|
"""A littlefs debug script. See -h/--help for more info."""
|
|
name = None
|
|
path = None
|
|
|
|
def __init__(self):
|
|
super().__init__(self.name,
|
|
gdb.COMMAND_DATA,
|
|
gdb.COMPLETE_EXPRESSION)
|
|
|
|
def invoke(self, args, *_):
|
|
# parse args
|
|
args = list(gdbsplit(args))
|
|
args_ = []
|
|
for a in args:
|
|
# pass flags as is
|
|
if a.startswith('-'):
|
|
args_.append(a)
|
|
|
|
# parse and eval
|
|
else:
|
|
try:
|
|
v = gdb.parse_and_eval(a)
|
|
t = v.type.strip_typedefs()
|
|
if t.code in {
|
|
gdb.TYPE_CODE_ENUM,
|
|
gdb.TYPE_CODE_FLAGS,
|
|
gdb.TYPE_CODE_INT,
|
|
gdb.TYPE_CODE_RANGE,
|
|
gdb.TYPE_CODE_CHAR,
|
|
gdb.TYPE_CODE_BOOL}:
|
|
v = str(int(v))
|
|
elif t.code in {
|
|
gdb.TYPE_CODE_FLT}:
|
|
v = str(float(v))
|
|
else:
|
|
try:
|
|
v = v.string('utf8')
|
|
except gdb.error:
|
|
raise gdb.GdbError('Unexpected type: %s' % v.type)
|
|
except gdb.error as e:
|
|
raise gdb.GdbError(e)
|
|
|
|
args_.append(shlex.quote(v))
|
|
args = args_
|
|
|
|
# execute
|
|
gdb.execute(' '.join(['!'+self.path, *args]))
|
|
|
|
|
|
# at some point this was manual, then I realized I could just glob all
|
|
# scripts with this prefix
|
|
#
|
|
# # dbgerr
|
|
# class DbgErr(DbgCommand):
|
|
# name = 'dbgerr'
|
|
# path = './scripts/dbgerr.py'
|
|
#
|
|
# # dbgflags
|
|
# class DbgFlags(DbgCommand):
|
|
# name = 'dbgflags'
|
|
# path = './scripts/dbgflags.py'
|
|
#
|
|
# # dbgtag
|
|
# class DbgTag(DbgCommand):
|
|
# name = 'dbgtag'
|
|
# path = './scripts/dbgtag.py'
|
|
|
|
import os
|
|
import glob
|
|
|
|
for path in glob.glob(os.path.join(
|
|
os.path.dirname(__file__),
|
|
'dbg*.py')):
|
|
if path == __file__:
|
|
continue
|
|
|
|
# create dbg class
|
|
name = os.path.splitext(os.path.basename(path))[0]
|
|
type(name, (DbgCommand,), {
|
|
'name': name,
|
|
'path': path
|
|
})
|
|
|
|
|
|
# initialize gdb hooks
|
|
for Dbg in DbgCommand.__subclasses__():
|
|
if Dbg.__doc__ is None:
|
|
Dbg.__doc__ = DbgCommand.__doc__
|
|
Dbg()
|