gdb/lists: optimize foreach list command

NuttX has various of list implementation, but the core of list is to
find next node, and stop iteration.

This change addes parameter of how to get next node by specifying its
element name.

Note the list head must be a pointer type.
E.g.
(gdb) foreach list -n next &g_msgfree
0: {prev = 0x40286200 <g_msgpool+280>, next = 0x4028628c <g_msgpool+420>}
1: {prev = 0x40286e30 <g_msgfree>, next = 0x40286318 <g_msgpool+560>}

(gdb) foreach list "(struct list_node *) 0x40286e30"
0: {prev = 0x40286200 <g_msgpool+280>, next = 0x4028628c <g_msgpool+420>}
1: {prev = 0x40286e30 <g_msgfree>, next = 0x40286318 <g_msgpool+560>}

(gdb) foreach list g_active_tcp_connections.head -n flink -c "struct tcp_conn_s" -m "sconn"                                                                                                                               13:14:07 [1047/1047]
0 @ *(struct tcp_conn_s *)0x40441510 {
  sconn = {
    node = {
      flink = 0x40441658 <g_tcp_connections+984>,
      blink = 0x0
    },
    list = 0x40443754 <g_cbprealloc+1488>,
    list_tail = 0x40443754 <g_cbprealloc+1488>,
    s_error = 0,
    s_options = 0,
    s_rcvtimeo = 0,
    s_sndtimeo = 0,
    s_boundto = 0 '\000',
    s_flags = 105 'i',
    s_tos = 0 '\000',
    s_ttl = 64 '@'
  },
  u = {
    ipv4 = {
      laddr = 16777343,
      raddr = 16777343
    },
    ipv6 = {
      laddr = {127, 256, 127, 256, 0, 0, 0, 0},
      raddr = {0, 0, 0, 0, 0, 0, 0, 0}
    }
  },
  rcvseq = "h\374\375\064",
  sndseq = "h\374\375\063",
  crefs = 1 '\001',
  domain = 2 '\002',
  sa = 0 '\000',
  sv = 12 '\f',
  rto = 12 '\f',
  tcpstateflags = 4 '\004',

Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
This commit is contained in:
xuxingliang 2024-10-29 10:47:32 +08:00 committed by Xiang Xiao
parent 8cda0c8648
commit cd3d639153

View file

@ -336,8 +336,19 @@ class ForeachListEntry(gdb.Command):
parser = argparse.ArgumentParser(description="Iterate the items in list")
parser.add_argument("head", type=str, help="List head")
parser.add_argument("type", type=str, help="Container type")
parser.add_argument("member", type=str, help="Member name in container")
parser.add_argument(
"-n",
"--next",
type=str,
help="The name of the next pointer in the list node",
default="next",
)
parser.add_argument(
"-c", "--container", type=str, default=None, help="Optional container type"
)
parser.add_argument(
"-m", "--member", type=str, default=None, help="Member name in container"
)
try:
args = parser.parse_args(argv)
except SystemExit:
@ -345,9 +356,19 @@ class ForeachListEntry(gdb.Command):
return
pointer = gdb.parse_and_eval(args.head)
container_type = gdb.lookup_type(args.type)
member = args.member
list = NxList(pointer, container_type, member)
for i, entry in enumerate(list):
node = pointer
i = 0
while node:
entry = (
utils.container_of(node, args.container, args.member)
if args.container
else node
)
entry = entry.dereference()
gdb.write(f"{i}: {entry.format_string(styling=True)}\n")
gdb.write(
f"{i} *({entry.type} *){hex(entry.address)} {entry.format_string(styling=True)}\n"
)
i += 1
node = node[args.next]
if node == pointer:
break