即使修复了漏洞,Valgrind仍然显示相同的内存泄漏

Valgrind shows same memory leaks even after fixing leaks

本文关键字:显示 泄漏 内存 Valgrind 漏洞      更新时间:2023-10-16

我们试图找出在Linux上运行的c++应用程序中的内存泄漏。我们正在使用Valgrind 3.6.0,并且已经能够获得一些"绝对丢失"的堆栈。在报告中,它还给出了"绝对丢失"字节的总数。

我们必须包含的修复是:将delete ptr更改为delete[] ptr,其中ptr指向堆上的位置数组。

请注意,ptr持有良好的内存量。我们也修复了许多其他类似的缺失。因此,我们期望泄漏减少。

但是在修复之后,奇怪的是Valgrind仍然在总结中报告了与之前相同数量的泄漏。

==00:00:15:13.661 14014== LEAK SUMMARY:
==00:00:15:13.661 14014==    definitely lost: 236 bytes in 8 blocks
==00:00:15:13.661 14014==    indirectly lost: 22,113 bytes in 17 blocks
==00:00:15:13.662 14014==      possibly lost: 695,006 bytes in 47 blocks
==00:00:15:13.662 14014==    still reachable: 2,056,059 bytes in 732 blocks
==00:00:15:13.662 14014==         suppressed: 0 bytes in 0 blocks
有人能解释一下Valgrind的这种行为吗?我们正在使用所有正确的选项来调用mem_check工具等

答案是,用错误类型的delete释放的块从未包含在泄漏报告中,因为valgrind意识到使用了错误类型的delete并报告了这一点,并释放了整个块。

我们可以通过一个简单的程序看到这种效果:

int main(int argc, char **argv)
{
  int *x = new int[20];
  delete x;
  return x != 0;
}

valgrind下运行时,报告:

==12212== Mismatched free() / delete / delete []
==12212==    at 0x61DCD1FC: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12212==    by 0x4005AC: main (x.c:7 in /tmp/x)
==12212==  Address 0x61fd4040 is 0 bytes inside a block of size 80 alloc'd
==12212==    at 0x61DCD967: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12212==    by 0x40059C: main (x.c:5 in /tmp/x)
==12212== 
==12212== 
==12212== HEAP SUMMARY:
==12212==     in use at exit: 0 bytes in 0 blocks
==12212==   total heap usage: 1 allocs, 1 frees, 80 bytes allocated
==12212== 
==12212== All heap blocks were freed -- no leaks are possible

所以它告诉你使用了错误的delete类型,但随后没有报告泄漏,因为它实际上在意识到你的错误后释放了整个块。

它报告为泄漏的东西是你根本没有试图释放的东西,如果你阅读泄漏报告,应该在泄漏摘要之前,然后valgrind会告诉你所有泄漏的内存被分配的确切位置,你应该能够跟踪这些泄漏并修复它们。