c++ - 解释 Valgrind 的 trace-malloc 输出

标签 c++ c malloc valgrind

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/

相关文章:

c++ - 版本号、次要号和发布号之间的区别

c++ - 为什么存储在 map 中时需要默认构造函数?

c - 如何监控程序调用的cpu指令

c - 如何纠正旧 GNU/Linux 机器上的整数溢出行为?

c - Keil C 编译器中的 strcpy 和 strcat

c - uchar 的模拟内存数组中的 int

c - 涉及 C free() 的单元测试

c++ - 如何确定要 dynamic_cast 到哪种类型?

c++ - 赋值中的表达式评估

c - 如何在linux中用C程序映射两个端口