From 6d2ebfdec6e7229c4d46d02d8e573663465d0c43 Mon Sep 17 00:00:00 2001 From: xuxingliang Date: Fri, 15 Nov 2024 10:43:44 +0800 Subject: [PATCH] mm: dump node overheadp during memdump Signed-off-by: xuxingliang --- mm/mempool/mempool.c | 15 ++++++----- mm/mm_heap/mm_memdump.c | 26 +++++++++++-------- tools/gdb/nuttxgdb/memdump.py | 23 ++++++++++++++--- tools/gdb/nuttxgdb/mm.py | 18 ++++++++++++-- tools/parsememdump.py | 47 +++++++++++++++++++---------------- 5 files changed, 84 insertions(+), 45 deletions(-) diff --git a/mm/mempool/mempool.c b/mm/mempool/mempool.c index 4ea7a9e783..ed8dd6a9e6 100644 --- a/mm/mempool/mempool.c +++ b/mm/mempool/mempool.c @@ -187,6 +187,7 @@ static void mempool_memdump_callback(FAR struct mempool_s *pool, FAR const void *input, FAR void *output) { size_t blocksize = MEMPOOL_REALBLOCKSIZE(pool); + size_t overhead = blocksize - pool->blocksize; FAR const struct mm_memdump_s *dump = input; if (buf->magic == MEMPOOL_MAGIC_FREE) @@ -206,8 +207,8 @@ static void mempool_memdump_callback(FAR struct mempool_s *pool, FAR const char *tmp = ""; # endif - syslog(LOG_INFO, "%6d%12zu%12lu%*p%s\n", - buf->pid, blocksize, buf->seqno, + syslog(LOG_INFO, "%6d%12zu%9zu%12lu%*p %s\n", + buf->pid, blocksize, overhead, buf->seqno, BACKTRACE_PTR_FMT_WIDTH, ((FAR char *)buf - pool->blocksize), tmp); } @@ -219,11 +220,12 @@ mempool_memdump_free_callback(FAR struct mempool_s *pool, FAR const void *input, FAR void *output) { size_t blocksize = MEMPOOL_REALBLOCKSIZE(pool); + size_t overhead = blocksize - pool->blocksize; if (buf->magic == MEMPOOL_MAGIC_FREE) { - syslog(LOG_INFO, "%12zu%*p\n", - blocksize, BACKTRACE_PTR_FMT_WIDTH, + syslog(LOG_INFO, "%12zu%9zu%*p\n", + blocksize, overhead, BACKTRACE_PTR_FMT_WIDTH, ((FAR char *)buf - pool->blocksize)); } } @@ -587,11 +589,12 @@ void mempool_memdump(FAR struct mempool_s *pool, } #else size_t blocksize = MEMPOOL_REALBLOCKSIZE(pool); + size_t overhead = blocksize - pool->blocksize; /* Avoid race condition */ - syslog(LOG_INFO, "%12zu%*p skip block dump\n", - blocksize, BACKTRACE_PTR_FMT_WIDTH, pool); + syslog(LOG_INFO, "%12zu%9zu%*p skip block dump\n", + blocksize, overhead, BACKTRACE_PTR_FMT_WIDTH, pool); #endif } diff --git a/mm/mm_heap/mm_memdump.c b/mm/mm_heap/mm_memdump.c index 11fc519286..b9684de454 100644 --- a/mm/mm_heap/mm_memdump.c +++ b/mm/mm_heap/mm_memdump.c @@ -60,13 +60,14 @@ struct mm_memdump_priv_s static void memdump_allocnode(FAR struct mm_allocnode_s *node) { size_t nodesize = MM_SIZEOF_NODE(node); + size_t overhead = MM_SIZEOF_ALLOCNODE; #if CONFIG_MM_BACKTRACE < 0 - syslog(LOG_INFO, "%12zu%*p\n", - nodesize, BACKTRACE_PTR_FMT_WIDTH, + syslog(LOG_INFO, "%12zu%9zu%*p\n", + nodesize, overhead, BACKTRACE_PTR_FMT_WIDTH, (FAR const char *)node + MM_SIZEOF_ALLOCNODE); #elif CONFIG_MM_BACKTRACE == 0 - syslog(LOG_INFO, "%6d%12zu%12lu%*p\n", - node->pid, nodesize, node->seqno, + syslog(LOG_INFO, "%6d%12zu%9zu%12lu%*p\n", + node->pid, nodesize, overhead, node->seqno, BACKTRACE_PTR_FMT_WIDTH, (FAR const char *)node + MM_SIZEOF_ALLOCNODE); #else @@ -75,8 +76,8 @@ static void memdump_allocnode(FAR struct mm_allocnode_s *node) backtrace_format(buf, sizeof(buf), node->backtrace, CONFIG_MM_BACKTRACE); - syslog(LOG_INFO, "%6d%12zu%12lu%*p %s\n", - node->pid, nodesize, node->seqno, + syslog(LOG_INFO, "%6d%12zu%9zu%12lu%*p %s\n", + node->pid, nodesize, overhead, node->seqno, BACKTRACE_PTR_FMT_WIDTH, (FAR const char *)node + MM_SIZEOF_ALLOCNODE, buf); #endif @@ -202,8 +203,8 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg) priv->info.aordblks++; priv->info.uordblks += nodesize; - syslog(LOG_INFO, "%12zu%*p\n", - nodesize, BACKTRACE_PTR_FMT_WIDTH, + syslog(LOG_INFO, "%12zu%9zu%*p\n", + nodesize, MM_ALLOCNODE_OVERHEAD, BACKTRACE_PTR_FMT_WIDTH, ((FAR char *)node + MM_SIZEOF_ALLOCNODE)); } } @@ -288,10 +289,13 @@ void mm_memdump(FAR struct mm_heap_s *heap, } #if CONFIG_MM_BACKTRACE < 0 - syslog(LOG_INFO, "%12s%*s\n", "Size", BACKTRACE_PTR_FMT_WIDTH, "Address"); + syslog(LOG_INFO, "%12s%9s%*s\n", "Size", "Overhead", + BACKTRACE_PTR_FMT_WIDTH, + "Address"); #else - syslog(LOG_INFO, "%6s%12s%12s%*s %s\n", "PID", "Size", "Sequence", - BACKTRACE_PTR_FMT_WIDTH, "Address", "Backtrace"); + syslog(LOG_INFO, "%6s%12s%9s%12s%*s %s\n", "PID", "Size", "Overhead", + "Sequence", BACKTRACE_PTR_FMT_WIDTH, + "Address", "Backtrace"); #endif memdump_dump_pool(&priv, heap); diff --git a/tools/gdb/nuttxgdb/memdump.py b/tools/gdb/nuttxgdb/memdump.py index 9135bc5d74..48f9191af4 100644 --- a/tools/gdb/nuttxgdb/memdump.py +++ b/tools/gdb/nuttxgdb/memdump.py @@ -92,7 +92,9 @@ def group_nodes( def print_node(node: MMNodeDump, alive, count=1, formatter=None, no_backtrace=False): - formatter = formatter or "{:>1} {:>4} {:>12} {:>12} {:>12} {:>14} {:>18} {:}\n" + formatter = ( + formatter or "{:>1} {:>4} {:>12} {:>12} {:>12} {:>9} {:>14} {:>18} {:}\n" + ) gdb.write( formatter.format( "\x1b[33;1m*\x1b[m" if not alive else "", @@ -100,6 +102,7 @@ def print_node(node: MMNodeDump, alive, count=1, formatter=None, no_backtrace=Fa count, node.pid, node.nodesize, + node.overhead, node.seqno, hex(node.address), "", @@ -107,15 +110,27 @@ def print_node(node: MMNodeDump, alive, count=1, formatter=None, no_backtrace=Fa ) if mm.CONFIG_MM_BACKTRACE and not no_backtrace: - leading = formatter.format("", "", "", "", "", "", "", "")[:-1] + leading = formatter.format("", "", "", "", "", "", "", "", "")[:-1] btformat = leading + "{1:<48}{2}\n" if node.backtrace and node.backtrace[0]: gdb.write(f"{utils.Backtrace(node.backtrace, formatter=btformat)}\n") def print_header(formatter=None): - formatter = formatter or "{:>1} {:>4} {:>12} {:>12} {:>12} {:>14} {:>18} {:}\n" - head = ("", "Pool", "CNT", "PID", "Size", "Seqno", "Address", "Backtrace") + formatter = ( + formatter or "{:>1} {:>4} {:>12} {:>12} {:>12} {:>9} {:>14} {:>18} {:}\n" + ) + head = ( + "", + "Pool", + "CNT", + "PID", + "Size", + "Overhead", + "Seqno", + "Address", + "Backtrace", + ) gdb.write(formatter.format(*head)) diff --git a/tools/gdb/nuttxgdb/mm.py b/tools/gdb/nuttxgdb/mm.py index c1943bbc68..4a785704d7 100644 --- a/tools/gdb/nuttxgdb/mm.py +++ b/tools/gdb/nuttxgdb/mm.py @@ -619,8 +619,20 @@ class MMPoolInfo(gdb.Command): gdb.write(f"Total {count} pools\n") name_max = max(len(pool.name) for pool in pools) + 11 # 11: "@0x12345678" - formatter = "{:>%d} {:>11} {:>9} {:>9} {:>9} {:>9} {:>9}\n" % name_max - head = ("", "total", "bsize", "nused", "nfree", "nifree", "nwaiter") + formatter = ( + "{:>%d} {:>11} {:>9} {:>9} {:>9} {:>9} {:>9} {:>9} {:>9}\n" % name_max + ) + head = ( + "", + "total", + "blocksize", + "bsize", + "overhead", + "nused", + "nfree", + "nifree", + "nwaiter", + ) gdb.write(formatter.format(*head)) for pool in pools: @@ -628,7 +640,9 @@ class MMPoolInfo(gdb.Command): formatter.format( f"{pool.name}@{pool.address:#x}", pool.total, + pool.blocksize, pool.size, + pool.overhead, pool.nused, pool.nfree, pool.nifree, diff --git a/tools/parsememdump.py b/tools/parsememdump.py index ee0b396815..f5faf56587 100755 --- a/tools/parsememdump.py +++ b/tools/parsememdump.py @@ -28,7 +28,7 @@ This program will help you analyze memdump log files, analyze the number of occurrences of backtrace, and output stack information memdump log files need this format: -pid size seq addr mem +pid size overhead seq addr mem """ @@ -37,26 +37,27 @@ class dump_line: self.mem = [] self.err = False self.cnt = 1 - tmp = re.search("( \d+ )", line_str) - if tmp is None: - self.err = True - return - self.pid = int(tmp.group(0)[1:]) - tmp = re.search("( \d+ )", line_str[tmp.span()[1] :]) - if tmp is None: - self.err = True - return - self.size = int(tmp.group(0)[1:]) - tmp = re.search("( \d+ )", line_str[tmp.span()[1] :]) - if tmp is None: - self.err = True - return - self.seq = int(tmp.group(0)[1:]) + self.pid = None + self.size = None + self.overhead = None + self.seq = None + self.addr = None + self.parse_line(line_str) - tmp = re.findall("0x([0-9a-fA-F]+)", line_str[tmp.span()[1] :]) - self.addr = tmp[0] - for s in tmp[1:]: - self.mem.append(s) + def parse_line(self, line_str): + match = re.search( + r"\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+((?:\s+0x[0-9a-fA-F]+)+)", line_str + ) + if match: + self.pid = int(match.group(1)) + self.size = int(match.group(2)) + self.overhead = int(match.group(3)) + self.seq = int(match.group(4)) + addresses = match.group(5).split() + self.addr = addresses[0] + self.mem = addresses[1:] + else: + self.err = True class log_output: @@ -204,7 +205,7 @@ if __name__ == "__main__": total_size += size log.output("all used memory %-6d\n" % (total_size)) - log.output("cnt size pid addr mem\n") + log.output("cnt size pid overhead addr mem\n") mems = [] for line in lines: @@ -221,7 +222,9 @@ if __name__ == "__main__": db = addr2line_db(mem=mems, ncpu=ncpu, prefix=args.prefix[0], file=args.elffile[0]) for t in lines: addr2line_str = "" - log.output("%-4d %-6d %-3d %s " % (t.cnt, t.size, t.pid, t.addr)) + log.output( + "%-4d %-6d %-6d %-3d %s " % (t.cnt, t.size, t.overhead, t.pid, t.addr) + ) if t.mem == []: log.output("\n") continue