mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 05:08:41 +08:00
mm: dump node overheadp during memdump
Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
This commit is contained in:
parent
797f7a043d
commit
6d2ebfdec6
5 changed files with 84 additions and 45 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue