You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/03/15 09:46:54 UTC

(nuttx) branch master updated: memdump: Enhance memdump

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 52a349ab13 memdump: Enhance memdump
52a349ab13 is described below

commit 52a349ab139f7fb3bd549e0151aeb226a299ee17
Author: wangmingrong <wa...@xiaomi.com>
AuthorDate: Tue Feb 27 16:26:30 2024 +0800

    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 <wa...@xiaomi.com>
---
 tools/gdb/memdump.py | 95 +++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 68 insertions(+), 27 deletions(-)

diff --git a/tools/gdb/memdump.py b/tools/gdb/memdump.py
index a53e20831f..5f0d1cc3f9 100644
--- a/tools/gdb/memdump.py
+++ b/tools/gdb/memdump.py
@@ -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()