我正在研究破坏堆的多线程 C++应用程序.找到这种腐败的常用工具似乎不适用.源代码的旧版本(18个月之前)表现出与最新版本相同的行为,因此这已经存在了很长时间并且没有被注意到; 在缺点方面,源增量不能用于识别何时引入错误 - 存储库中存在大量代码更改.
崩溃行为的提示是在这个系统中产生吞吐量 - 数据的套接字传输,它被导入内部表示.我有一组测试数据会定期导致应用程序异常(各种地方,各种原因 - 包括堆分配失败,因此:堆损坏).
行为似乎与CPU功率或内存带宽有关; 机器越多,崩溃就越容易.禁用超线程核心或双核核心可降低(但不消除)损坏的速度.这表明与时间相关的问题.
现在这里有一个问题:
当它在一个轻量级的调试环境下运行时(比方说Visual Studio 98 / AKA MSVC6),堆损坏相当容易重现 - 在事情失败和异常失败之前经过十或十五分钟,就像alloc;在复杂的调试环境下运行时一样(Rational Purify,VS2008/MSVC9或者甚至是微软应用程序验证程序)系统变得内存速度受限并且不会崩溃(内存限制:CPU没有达到上面50%,磁盘指示灯不亮,程序运行速度快,盒子消耗1.3G2G RAM) .因此,我可以选择能够重现问题(但不能确定原因)或能够识别原因或我无法重现的问题.
我目前最好的猜测是下一步是:
E6550 Core2 Duo); 这样可以在强大的调试环境下运行时重现崩溃导致错误行为; 要么new并delete使用VirtualAlloc并VirtualProtect在完成后将内存标记为只读.运行MSVC6并让操作系统捕获正在写入释放内存的坏人.是的,这是绝望的标志:谁是地狱重写new和delete?!我想知道这是否会使它像Purify等人一样慢.而且,不是:内置Purify仪器的运输不是一种选择.
一位同事刚刚走过去问"Stack Overflow?我们现在收到堆栈溢出了吗?!?"
现在,问题是:我如何找到堆腐败者?
更新:平衡new[],delete[]似乎已经有很长的路要走解决问题.而不是15分钟,应用程序现在大约两个小时崩溃.还没有.还有什么建议?堆损坏仍然存在.
更新:Visual Studio 2008下的发布版本似乎要好得多; 目前的怀疑依赖于STL随船携带的实施VS98. …