gdb: add custom cmd for printing linked list
This commit is contained in:
parent
31aaf10635
commit
220597a881
@ -136,6 +136,92 @@ class PhyMemDescListDumpCmd(gdb.Command):
|
||||
print(self._phy_memDesc_lit_to_str(desc))
|
||||
|
||||
|
||||
class PrintStructC99Cmd(gdb.Command):
|
||||
def __init__(self):
|
||||
super(PrintStructC99Cmd, self).__init__(
|
||||
"print_struct_c99",
|
||||
gdb.COMMAND_USER,
|
||||
)
|
||||
|
||||
def complete(self, text, word):
|
||||
return gdb.COMPLETE_SYMBOL
|
||||
|
||||
def get_count_heading(self, string):
|
||||
for i, s in enumerate(string):
|
||||
if s != ' ':
|
||||
break
|
||||
return i
|
||||
|
||||
def extract_typename(self, string):
|
||||
first_line = string.split('\n')[0]
|
||||
return first_line.split('=')[1][:-1].strip()
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
gdb.execute("set print pretty")
|
||||
gdb.execute('set pagination off')
|
||||
gdb.execute('set print repeats 0')
|
||||
gdb.execute('set print elements unlimited')
|
||||
ret_ptype = gdb.execute('ptype {}'.format(arg), to_string=True)
|
||||
tname = self.extract_typename(ret_ptype)
|
||||
print('{} {} = {{'.format(tname, arg))
|
||||
r = gdb.execute('p {}'.format(arg), to_string=True)
|
||||
r = r.split('\n')
|
||||
for rr in r[1:]:
|
||||
if '=' not in rr:
|
||||
print(rr)
|
||||
continue
|
||||
hs = self.get_count_heading(rr)
|
||||
rr_s = rr.strip().split('=', 1)
|
||||
rr_rval = rr_s[1].strip()
|
||||
print(' ' * hs + '.' + rr_s[0] + '= ' + rr_rval)
|
||||
|
||||
class ListDumpCmd(gdb.Command):
|
||||
"""Prints a linked list"""
|
||||
|
||||
def __init__(self):
|
||||
super(ListDumpCmd, self).__init__(
|
||||
"list_dump", gdb.COMMAND_USER
|
||||
)
|
||||
|
||||
def _print_list(self, val):
|
||||
"""Walk through the linked list.
|
||||
|
||||
We will simply follow the 'next' pointers until we encounter the HEAD again
|
||||
"""
|
||||
idx = 0
|
||||
head = val
|
||||
kthread_ptr = val
|
||||
result = ""
|
||||
while kthread_ptr != 0 and (idx == 0 or kthread_ptr != head):
|
||||
result += gdb.execute('p *({}){}'.format(str(kthread_ptr.type),kthread_ptr), to_string=True)
|
||||
kthread_ptr = kthread_ptr["next"]
|
||||
idx += 1
|
||||
result = ("Found a Linked List with %d items:" % idx) + "\n"+ result
|
||||
return result
|
||||
|
||||
def complete(self, text, word):
|
||||
# We expect the argument passed to be a symbol so fallback to the
|
||||
# internal tab-completion handler for symbols
|
||||
return gdb.COMPLETE_SYMBOL
|
||||
|
||||
def invoke(self, args, from_tty):
|
||||
# We can pass args here and use Python CLI utilities like argparse
|
||||
# to do argument parsing
|
||||
print("Args Passed: %s" % args)
|
||||
if args:
|
||||
ptr_val = gdb.parse_and_eval(args)
|
||||
else:
|
||||
ptr_val = gdb.parse_and_eval("currentThread")
|
||||
try:
|
||||
ptr_val["next"]
|
||||
except:
|
||||
print("Expected pointer argument with a next field")
|
||||
return
|
||||
|
||||
print(self._print_list(ptr_val))
|
||||
|
||||
register_pretty_printer(None, CustomPrettyPrinterLocator(), replace=True)
|
||||
KthreadListDumpCmd()
|
||||
PhyMemDescListDumpCmd()
|
||||
PrintStructC99Cmd()
|
||||
ListDumpCmd()
|
||||
|
Loading…
Reference in New Issue
Block a user