mm: dump node overheadp during memdump

Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
This commit is contained in:
xuxingliang 2024-11-15 10:43:44 +08:00 committed by Xiang Xiao
parent 797f7a043d
commit 6d2ebfdec6
5 changed files with 84 additions and 45 deletions

View file

@ -187,6 +187,7 @@ static void mempool_memdump_callback(FAR struct mempool_s *pool,
FAR const void *input, FAR void *output) FAR const void *input, FAR void *output)
{ {
size_t blocksize = MEMPOOL_REALBLOCKSIZE(pool); size_t blocksize = MEMPOOL_REALBLOCKSIZE(pool);
size_t overhead = blocksize - pool->blocksize;
FAR const struct mm_memdump_s *dump = input; FAR const struct mm_memdump_s *dump = input;
if (buf->magic == MEMPOOL_MAGIC_FREE) if (buf->magic == MEMPOOL_MAGIC_FREE)
@ -206,8 +207,8 @@ static void mempool_memdump_callback(FAR struct mempool_s *pool,
FAR const char *tmp = ""; FAR const char *tmp = "";
# endif # endif
syslog(LOG_INFO, "%6d%12zu%12lu%*p%s\n", syslog(LOG_INFO, "%6d%12zu%9zu%12lu%*p %s\n",
buf->pid, blocksize, buf->seqno, buf->pid, blocksize, overhead, buf->seqno,
BACKTRACE_PTR_FMT_WIDTH, BACKTRACE_PTR_FMT_WIDTH,
((FAR char *)buf - pool->blocksize), tmp); ((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) FAR const void *input, FAR void *output)
{ {
size_t blocksize = MEMPOOL_REALBLOCKSIZE(pool); size_t blocksize = MEMPOOL_REALBLOCKSIZE(pool);
size_t overhead = blocksize - pool->blocksize;
if (buf->magic == MEMPOOL_MAGIC_FREE) if (buf->magic == MEMPOOL_MAGIC_FREE)
{ {
syslog(LOG_INFO, "%12zu%*p\n", syslog(LOG_INFO, "%12zu%9zu%*p\n",
blocksize, BACKTRACE_PTR_FMT_WIDTH, blocksize, overhead, BACKTRACE_PTR_FMT_WIDTH,
((FAR char *)buf - pool->blocksize)); ((FAR char *)buf - pool->blocksize));
} }
} }
@ -587,11 +589,12 @@ void mempool_memdump(FAR struct mempool_s *pool,
} }
#else #else
size_t blocksize = MEMPOOL_REALBLOCKSIZE(pool); size_t blocksize = MEMPOOL_REALBLOCKSIZE(pool);
size_t overhead = blocksize - pool->blocksize;
/* Avoid race condition */ /* Avoid race condition */
syslog(LOG_INFO, "%12zu%*p skip block dump\n", syslog(LOG_INFO, "%12zu%9zu%*p skip block dump\n",
blocksize, BACKTRACE_PTR_FMT_WIDTH, pool); blocksize, overhead, BACKTRACE_PTR_FMT_WIDTH, pool);
#endif #endif
} }

View file

@ -60,13 +60,14 @@ struct mm_memdump_priv_s
static void memdump_allocnode(FAR struct mm_allocnode_s *node) static void memdump_allocnode(FAR struct mm_allocnode_s *node)
{ {
size_t nodesize = MM_SIZEOF_NODE(node); size_t nodesize = MM_SIZEOF_NODE(node);
size_t overhead = MM_SIZEOF_ALLOCNODE;
#if CONFIG_MM_BACKTRACE < 0 #if CONFIG_MM_BACKTRACE < 0
syslog(LOG_INFO, "%12zu%*p\n", syslog(LOG_INFO, "%12zu%9zu%*p\n",
nodesize, BACKTRACE_PTR_FMT_WIDTH, nodesize, overhead, BACKTRACE_PTR_FMT_WIDTH,
(FAR const char *)node + MM_SIZEOF_ALLOCNODE); (FAR const char *)node + MM_SIZEOF_ALLOCNODE);
#elif CONFIG_MM_BACKTRACE == 0 #elif CONFIG_MM_BACKTRACE == 0
syslog(LOG_INFO, "%6d%12zu%12lu%*p\n", syslog(LOG_INFO, "%6d%12zu%9zu%12lu%*p\n",
node->pid, nodesize, node->seqno, node->pid, nodesize, overhead, node->seqno,
BACKTRACE_PTR_FMT_WIDTH, BACKTRACE_PTR_FMT_WIDTH,
(FAR const char *)node + MM_SIZEOF_ALLOCNODE); (FAR const char *)node + MM_SIZEOF_ALLOCNODE);
#else #else
@ -75,8 +76,8 @@ static void memdump_allocnode(FAR struct mm_allocnode_s *node)
backtrace_format(buf, sizeof(buf), node->backtrace, backtrace_format(buf, sizeof(buf), node->backtrace,
CONFIG_MM_BACKTRACE); CONFIG_MM_BACKTRACE);
syslog(LOG_INFO, "%6d%12zu%12lu%*p %s\n", syslog(LOG_INFO, "%6d%12zu%9zu%12lu%*p %s\n",
node->pid, nodesize, node->seqno, node->pid, nodesize, overhead, node->seqno,
BACKTRACE_PTR_FMT_WIDTH, BACKTRACE_PTR_FMT_WIDTH,
(FAR const char *)node + MM_SIZEOF_ALLOCNODE, buf); (FAR const char *)node + MM_SIZEOF_ALLOCNODE, buf);
#endif #endif
@ -202,8 +203,8 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
priv->info.aordblks++; priv->info.aordblks++;
priv->info.uordblks += nodesize; priv->info.uordblks += nodesize;
syslog(LOG_INFO, "%12zu%*p\n", syslog(LOG_INFO, "%12zu%9zu%*p\n",
nodesize, BACKTRACE_PTR_FMT_WIDTH, nodesize, MM_ALLOCNODE_OVERHEAD, BACKTRACE_PTR_FMT_WIDTH,
((FAR char *)node + MM_SIZEOF_ALLOCNODE)); ((FAR char *)node + MM_SIZEOF_ALLOCNODE));
} }
} }
@ -288,10 +289,13 @@ void mm_memdump(FAR struct mm_heap_s *heap,
} }
#if CONFIG_MM_BACKTRACE < 0 #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 #else
syslog(LOG_INFO, "%6s%12s%12s%*s %s\n", "PID", "Size", "Sequence", syslog(LOG_INFO, "%6s%12s%9s%12s%*s %s\n", "PID", "Size", "Overhead",
BACKTRACE_PTR_FMT_WIDTH, "Address", "Backtrace"); "Sequence", BACKTRACE_PTR_FMT_WIDTH,
"Address", "Backtrace");
#endif #endif
memdump_dump_pool(&priv, heap); memdump_dump_pool(&priv, heap);

View file

@ -92,7 +92,9 @@ def group_nodes(
def print_node(node: MMNodeDump, alive, count=1, formatter=None, no_backtrace=False): 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( gdb.write(
formatter.format( formatter.format(
"\x1b[33;1m*\x1b[m" if not alive else "", "\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, count,
node.pid, node.pid,
node.nodesize, node.nodesize,
node.overhead,
node.seqno, node.seqno,
hex(node.address), 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: if mm.CONFIG_MM_BACKTRACE and not no_backtrace:
leading = formatter.format("", "", "", "", "", "", "", "")[:-1] leading = formatter.format("", "", "", "", "", "", "", "", "")[:-1]
btformat = leading + "{1:<48}{2}\n" btformat = leading + "{1:<48}{2}\n"
if node.backtrace and node.backtrace[0]: if node.backtrace and node.backtrace[0]:
gdb.write(f"{utils.Backtrace(node.backtrace, formatter=btformat)}\n") gdb.write(f"{utils.Backtrace(node.backtrace, formatter=btformat)}\n")
def print_header(formatter=None): def print_header(formatter=None):
formatter = formatter or "{:>1} {:>4} {:>12} {:>12} {:>12} {:>14} {:>18} {:}\n" formatter = (
head = ("", "Pool", "CNT", "PID", "Size", "Seqno", "Address", "Backtrace") 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)) gdb.write(formatter.format(*head))

View file

@ -619,8 +619,20 @@ class MMPoolInfo(gdb.Command):
gdb.write(f"Total {count} pools\n") gdb.write(f"Total {count} pools\n")
name_max = max(len(pool.name) for pool in pools) + 11 # 11: "@0x12345678" name_max = max(len(pool.name) for pool in pools) + 11 # 11: "@0x12345678"
formatter = "{:>%d} {:>11} {:>9} {:>9} {:>9} {:>9} {:>9}\n" % name_max formatter = (
head = ("", "total", "bsize", "nused", "nfree", "nifree", "nwaiter") "{:>%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)) gdb.write(formatter.format(*head))
for pool in pools: for pool in pools:
@ -628,7 +640,9 @@ class MMPoolInfo(gdb.Command):
formatter.format( formatter.format(
f"{pool.name}@{pool.address:#x}", f"{pool.name}@{pool.address:#x}",
pool.total, pool.total,
pool.blocksize,
pool.size, pool.size,
pool.overhead,
pool.nused, pool.nused,
pool.nfree, pool.nfree,
pool.nifree, pool.nifree,

View file

@ -28,7 +28,7 @@ This program will help you analyze memdump log files,
analyze the number of occurrences of backtrace, analyze the number of occurrences of backtrace,
and output stack information and output stack information
memdump log files need this format: 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.mem = []
self.err = False self.err = False
self.cnt = 1 self.cnt = 1
tmp = re.search("( \d+ )", line_str) self.pid = None
if tmp is None: self.size = None
self.err = True self.overhead = None
return self.seq = None
self.pid = int(tmp.group(0)[1:]) self.addr = None
tmp = re.search("( \d+ )", line_str[tmp.span()[1] :]) self.parse_line(line_str)
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:])
tmp = re.findall("0x([0-9a-fA-F]+)", line_str[tmp.span()[1] :]) def parse_line(self, line_str):
self.addr = tmp[0] match = re.search(
for s in tmp[1:]: r"\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+((?:\s+0x[0-9a-fA-F]+)+)", line_str
self.mem.append(s) )
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: class log_output:
@ -204,7 +205,7 @@ if __name__ == "__main__":
total_size += size total_size += size
log.output("all used memory %-6d\n" % (total_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 = [] mems = []
for line in lines: 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]) db = addr2line_db(mem=mems, ncpu=ncpu, prefix=args.prefix[0], file=args.elffile[0])
for t in lines: for t in lines:
addr2line_str = "" 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 == []: if t.mem == []:
log.output("\n") log.output("\n")
continue continue