Valgrind 是一个出色的内存调试器,它有选项 --trace-malloc=yes
,它产生如下内容:
--16301-- malloc(8) = 0x4EAD748
--16301-- free(0x4EAD748)
--16301-- free(0x4EAD498)
--16301-- malloc(21) = 0x4EAD780
--16301-- malloc(8) = 0x4EAD838
--16301-- free(0x4EAD6F8)
--16301-- calloc(1,88) = 0x4EAD870
--16301-- realloc(0x0,160)malloc(160) = 0x4EB1CF8
--16301-- realloc(0x4EB9F28,4) = 0x4EBA060
是否有工具可以解析此输出并针对每个地址告诉我它是否未正确分配并在匹配对中释放?
GCC 有类似mtrace()
函数和mtrace
命令行工具,只是格式不同。
奖励问题:是否可以在“definitely lost”语句旁边输出实际地址?
(我将这个“C”和“C++”标记为最有可能与 Valgrind 一起使用的两种语言。)
最佳答案
输出似乎是部分输出(或者它来自严重损坏的代码。然而,这似乎是匹配地址的简单 perl 脚本的工作。实际上,对于 C++2011 的正则表达式,甚至 C++ 也应该完成任务,但我还没有使用过这些。所以,这是一个简单的(虽然可能相当笨拙)perl 脚本,它从标准输入读取 valgrind 的输出:
#!/usr/bin/perl -w
use strict;
my %allocated;
while (<>)
{
chomp;
if (/(realloc\(([^,]*),([^)]*)\)).* = (.*)/)
{
if ($2 ne "0x0")
{
if (!exists $allocated{$2})
{
print "spurious realloc($2, $3) = $4\n";
}
else
{
delete $allocated{$2};
}
}
$allocated{$4} = "$1$;$3";
}
elsif (/(malloc\((.*)\)) = (.*)/)
{
$allocated{$3} = "$1$;$2";
}
elsif (/ free\((.*)\)/)
{
if ($1 ne "0x0")
{
if (!exists $allocated{$1})
{
print "spurious free($1)\n";
}
else
{
delete $allocated{$1};
}
}
}
elsif (/(calloc\((.*),(.*)\)) = (.*)/)
{
$allocated{$4} = "$1$;" . ($2 * $3);
}
}
my $total = 0;
foreach my $leak (keys %allocated)
{
my($call, $size) = split(/$;/, $allocated{$leak});
print "leak: address=$leak source=$call size=$size\n";
$total += $size;
}
if (0 < $total)
{
print "total leak=$total\n";
}
关于c++ - 解释 Valgrind 的 trace-malloc 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8751634/