很难跟踪内存损坏 – 运行Valgrind时运行正常,没有错误

我们有一个复杂的程序,在重载输入(实际上是任何输入)上运行良好,没有实现multithreading。
我们用线程池实现了multithreading,给定这些输入参数我得到了这些结果:
注意 :我说没有错误 ,这意味着我已经用valgrind -v进行了测试,当我说没有内存泄漏时 ,这意味着我已经用valgrind --leak-check=full -v测试了它)。

  1. small_file:成功运行超过1个worker(线程),没有valgrind错误,没有内存泄漏
  2. medium_file:使用1个worker成功运行,没有错误/内存泄漏。 有> 1名工人,我得到:a。 通常是堆损坏错误,b。 双自由。 当使用valgrind -v运行> 1个worker时,程序成功完成。 此外,没有从valgrind打印错误,即ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

现在我从valgrind开始没有得到任何错误,我该怎么做才能找到这个复杂而庞大的应用程序中的内存损坏问题?

DevelopmentEnvironment:
Ubuntu,64bit,gcc版本:4.7.2和4.8.1(不同的计算机,更新版本的Ubuntu)。

有> 1名工人,我得到:a。 通常是堆损坏错误,b.double-free。 当使用valgrind -v运行> 1个worker时,程序成功完成

基于上述症状,我认为您的程序中明显存在某种同步问题。 看起来你的程序正在共享线程之间的堆内存地址,因此每当有一些数据竞争时你就会遇到问题。

您还提到当您运行valgrind -v时,您的程序已成功完成。 这表明您的程序存在同步问题,并且该程序也依赖于序列/时序。 这些是最难找到的错误之一。我们还应该记住,在程序运行并执行错误之前,动态工具不会发出任何警告。 我的意思是程序中可能存在问题,但执行顺序(因为存在一些与时间相关的问题)确定工具是否会捕获这些故障。

话虽如此,我认为在大型程序中找不到这样的错误并没有减少方法。但是我强烈怀疑存在一些导致内存损坏/双重释放的数据竞争场景。 因此,您可能希望使用Helgrind来检查/查找可能导致内存损坏的数据竞争/线程问题。

现在我从valgrind开始没有得到任何错误,我该怎么做才能找到这个复杂而庞大的应用程序中的内存损坏问题?

好吧,让我向您描述我在20世纪90年代在微软的JavaScript实现中发现内存泄漏的方法。

首先,我确保在我的程序的调试版本中,尽可能多的内存分配被路由到相同的帮助器方法。 也就是说,我将mallocnew等重新定义为我自己编写的分配器的所有同义词。

该分配器只是一个围绕操作系统虚拟堆内存分配器的薄shell,但它有一些额外的智能。 它在块的开头和结尾分配了额外的内存,并用sentinel值,到目前为止的分配数量的线程安全计数以及所有分配的线程安全双向链表填充。 “免费”例程将validation双方的哨兵值仍然完好无损; 如果没有,那么某处存在内存损坏。 它会将块与链接列表取消链接并释放它。

在任何时候,我都可以按照分配顺序向内存管理器询问内存中所有未完成块的列表。 卸载DLL时列表中剩余的任何项目都是内存泄漏。

这些工具使我能够非常容易地实时发现内存泄漏和内存损坏。

请使用CORE DUMP :: [主要用于双无,glibc检测到的类型错误]

使用gcc -g选项编译程序以获取调试信息

ulimit -a

它会显示核心文件的大小

ulimit -c无限制

它将设置核心文件的大小无限制

现在运行程序,然后在当前目录中生成一个名为“core”的文件

然后通过GDB分析如下..

gdb ./youprogram核心

GDB)BT

它会告诉你哪里有问题..

如果你发现任何困难,请写信给我……