forked from nuttx/nuttx-update
memdump: Enhance memdump
The method of passing in parameters to memdump is modified and the incoming address is added. After traversing the node to which the address belongs, the memdump command will end. Signed-off-by: wangmingrong <wangmingrong@xiaomi.com>
This commit is contained in:
parent
ac7433eb5a
commit
52a349ab13
1 changed files with 68 additions and 27 deletions
|
@ -18,6 +18,8 @@
|
|||
#
|
||||
############################################################################
|
||||
|
||||
import argparse
|
||||
|
||||
import gdb
|
||||
import utils
|
||||
from lists import list_for_each_entry, sq_for_every, sq_queue
|
||||
|
@ -35,6 +37,11 @@ PID_MM_LEAK = -2
|
|||
PID_MM_MEMPOOL = -1
|
||||
|
||||
|
||||
def mm_nodesize(size) -> int:
|
||||
"""Return the real size of a memory node"""
|
||||
return size & ~MM_MASK_BIT
|
||||
|
||||
|
||||
def mm_foreach(heap):
|
||||
"""Iterate over a heap, yielding each node"""
|
||||
node = gdb.Value(heap["mm_heapstart"][0]).cast(
|
||||
|
@ -43,7 +50,7 @@ def mm_foreach(heap):
|
|||
while 1:
|
||||
yield node
|
||||
next = gdb.Value(node).cast(gdb.lookup_type("char").pointer())
|
||||
next = gdb.Value(next + (node["size"] & ~MM_MASK_BIT)).cast(
|
||||
next = gdb.Value(next + mm_nodesize(node["size"])).cast(
|
||||
gdb.lookup_type("struct mm_allocnode_s").pointer()
|
||||
)
|
||||
if node >= heap["mm_heapend"].dereference() or next == node:
|
||||
|
@ -66,7 +73,7 @@ class Nxmemdump(gdb.Command):
|
|||
def __init__(self):
|
||||
super(Nxmemdump, self).__init__("memdump", gdb.COMMAND_USER)
|
||||
|
||||
def mempool_dump(self, mpool, pid, seqmin, seqmax):
|
||||
def mempool_dump(self, mpool, pid, seqmin, seqmax, address):
|
||||
"""Dump the mempool memory"""
|
||||
for pool in mempool_multiple_foreach(mpool):
|
||||
if pid == PID_MM_FREE:
|
||||
|
@ -95,7 +102,7 @@ class Nxmemdump(gdb.Command):
|
|||
"%6d%12u%12u%#*x"
|
||||
% (
|
||||
node["pid"],
|
||||
pool["blocksize"] & ~MM_MASK_BIT,
|
||||
mm_nodesize(pool["blocksize"]),
|
||||
node["seqno"],
|
||||
self.align,
|
||||
(int)(charnode - pool["blocksize"]),
|
||||
|
@ -111,11 +118,23 @@ class Nxmemdump(gdb.Command):
|
|||
)
|
||||
)
|
||||
|
||||
if address and (
|
||||
address < int(charnode)
|
||||
and address >= (int)(charnode - pool["blocksize"])
|
||||
):
|
||||
gdb.write(
|
||||
"\nThe address 0x%x found belongs to"
|
||||
"the mempool node with base address 0x%x\n"
|
||||
% (address, charnode)
|
||||
)
|
||||
return True
|
||||
|
||||
gdb.write("\n")
|
||||
self.aordblks += 1
|
||||
self.uordblks += pool["blocksize"]
|
||||
return False
|
||||
|
||||
def memdump(self, pid, seqmin, seqmax):
|
||||
def memdump(self, pid, seqmin, seqmax, address):
|
||||
"""Dump the heap memory"""
|
||||
if pid >= PID_MM_ALLOC:
|
||||
gdb.write("Dump all used memory node info:\n")
|
||||
|
@ -129,7 +148,8 @@ class Nxmemdump(gdb.Command):
|
|||
|
||||
heap = gdb.parse_and_eval("g_mmheap")
|
||||
if heap.type.has_key("mm_mpool"):
|
||||
self.mempool_dump(heap["mm_mpool"], pid, seqmin, seqmax)
|
||||
if self.mempool_dump(heap["mm_mpool"], pid, seqmin, seqmax, address):
|
||||
return
|
||||
|
||||
for node in mm_foreach(heap):
|
||||
if node["size"] & MM_ALLOC_BIT != 0:
|
||||
|
@ -142,7 +162,7 @@ class Nxmemdump(gdb.Command):
|
|||
"%6d%12u%12u%#*x"
|
||||
% (
|
||||
node["pid"],
|
||||
node["size"] & ~MM_MASK_BIT,
|
||||
mm_nodesize(node["size"]),
|
||||
node["seqno"],
|
||||
self.align,
|
||||
(int)(
|
||||
|
@ -164,15 +184,29 @@ class Nxmemdump(gdb.Command):
|
|||
|
||||
gdb.write("\n")
|
||||
|
||||
if address and (
|
||||
address < int(charnode + node["size"])
|
||||
and address
|
||||
>= (int)(
|
||||
charnode + gdb.lookup_type("struct mm_allocnode_s").sizeof
|
||||
)
|
||||
):
|
||||
gdb.write(
|
||||
"\nThe address 0x%x found belongs to"
|
||||
"the memory node with base address 0x%x\n"
|
||||
% (address, charnode)
|
||||
)
|
||||
return
|
||||
|
||||
self.aordblks += 1
|
||||
self.uordblks += node["size"] & ~MM_MASK_BIT
|
||||
self.uordblks += mm_nodesize(node["size"])
|
||||
else:
|
||||
if pid == PID_MM_FREE:
|
||||
charnode = gdb.Value(node).cast(gdb.lookup_type("char").pointer())
|
||||
gdb.write(
|
||||
"%12u%#*x\n"
|
||||
% (
|
||||
node["size"] & ~MM_MASK_BIT,
|
||||
mm_nodesize(node["size"]),
|
||||
self.align,
|
||||
(int)(
|
||||
charnode
|
||||
|
@ -181,7 +215,7 @@ class Nxmemdump(gdb.Command):
|
|||
)
|
||||
)
|
||||
self.aordblks += 1
|
||||
self.uordblks += node["size"] & ~MM_MASK_BIT
|
||||
self.uordblks += mm_nodesize(node["size"])
|
||||
|
||||
gdb.write("%12s%12s\n" % ("Total Blks", "Total Size"))
|
||||
gdb.write("%12d%12d\n" % (self.aordblks, self.uordblks))
|
||||
|
@ -189,36 +223,43 @@ class Nxmemdump(gdb.Command):
|
|||
def complete(self, text, word):
|
||||
return gdb.COMPLETE_SYMBOL
|
||||
|
||||
def parse_arguments(self, argv):
|
||||
parser = argparse.ArgumentParser(description="memdump command")
|
||||
parser.add_argument("-p", "--pid", type=str, help="Thread PID")
|
||||
parser.add_argument("-a", "--addr", type=str, help="Query memory address")
|
||||
parser.add_argument("-i", "--min", type=str, help="Minimum value")
|
||||
parser.add_argument("-x", "--max", type=str, help="Maximum value")
|
||||
parser.add_argument("--used", action="store_true", help="Used flag")
|
||||
parser.add_argument("--free", action="store_true", help="Free flag")
|
||||
args = parser.parse_args(args=(None if len(argv) == 1 else argv))
|
||||
return {
|
||||
"pid": int(args.pid, 0) if args.pid else None,
|
||||
"seqmin": int(args.min, 0) if args.min else 0,
|
||||
"seqmax": int(args.max, 0) if args.max else 0xFFFFFFFF,
|
||||
"used": args.used,
|
||||
"free": args.free,
|
||||
"addr": int(args.addr, 0) if args.addr else None,
|
||||
}
|
||||
|
||||
def invoke(self, args, from_tty):
|
||||
if gdb.lookup_type("size_t").sizeof == 4:
|
||||
self.align = 11
|
||||
else:
|
||||
self.align = 19
|
||||
|
||||
arg = args.split(" ")
|
||||
arg = self.parse_arguments(args.split(" "))
|
||||
|
||||
if arg[0] == "":
|
||||
pid = PID_MM_ALLOC
|
||||
if arg["used"]:
|
||||
pid = PID_MM_ALLOC
|
||||
elif arg[0] == "used":
|
||||
pid = PID_MM_ALLOC
|
||||
elif arg[0] == "free":
|
||||
elif arg["free"]:
|
||||
pid = PID_MM_LEAK
|
||||
else:
|
||||
pid = int(arg[0])
|
||||
|
||||
if len(arg) == 2:
|
||||
seqmin = int(arg[1])
|
||||
else:
|
||||
seqmin = 0
|
||||
|
||||
if len(arg) == 3:
|
||||
seqmax = int(arg[2])
|
||||
else:
|
||||
seqmax = 0xFFFFFFFF
|
||||
elif arg["pid"]:
|
||||
pid = arg["pid"]
|
||||
|
||||
self.aordblks = 0
|
||||
self.uordblks = 0
|
||||
self.memdump(pid, seqmin, seqmax)
|
||||
self.memdump(pid, arg["seqmin"], arg["seqmax"], arg["addr"])
|
||||
|
||||
|
||||
Nxmemdump()
|
||||
|
|
Loading…
Reference in a new issue