2011-08-04 20 views
9

我工作的软件(使用C++编写)目前存在堆损坏问题。我们的性能测试团队在登录到盒子的用户数量达到某个阈值时仍然会收到WER错误,但他们给我的转储只是在不明显的区域显示损坏(例如,当std :: string释放它的基础内存时) 。查找只发生在性能测试下的堆损坏的最佳方式是什么?

我试过使用AppApprifier,这确实引发了一些我现在修复的问题。然而,我现在处于这样一种情况,即测试人员可以尽可能多地使用AppApprifier加载机器,并且运行干净,但在没有AppApprifier的情况下运行时仍然会发生堆损坏(我想因为他们可以在没有其他用户的情况下获得更多用户)。这意味着我一直无法获得实际显示问题的转储。

有没有人有任何其他的想法,我可以使用有用的技术或技术?我已经做了尽可能多的分析,因为我可以在堆腐败转储没有appverifier,但我看不到任何常见的主题。没有任何线程在崩溃的同时做任何事情,而且崩溃的线程是无辜的,这使我认为腐败发生在前一段时间。

+0

任何机会,你的代码是否可移植到* nix上?如果是这样,启动'valgrind'(或在Windows上找到类似的工具):通常第一个抱怨“无效读取”或“无效写入”是一个很好的暗示,因为真正的错误在哪里。 – ereOn

+0

啊,只要它是:-)我以前用过valgrind,它是一个很好的工具。 Appverifier通常也很方便,但在这种情况下,它并不适用于我:-( – Benj

+0

在另一个(有点类似)的问题上,我建议将电子围栏移植到Windows上,它会在无数内存错误中故意对段进行故障排序,但我很不确定http://code.google.com/p/electric-fence-win32/ –

回答

6

最好的工具是AppFrifier与gFlags结合使用,但还有很多其他解决方案可能有所帮助。

例如,你可以指定一个堆检查每16个的malloc,realloc的,免费的,_msize操作用下面的代码:

#include <crtdbg.h> 
int main() 
{ 
int tmp; 

// Get the current bits 
tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 

// Clear the upper 16 bits and OR in the desired freqency 
tmp = (tmp & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF; 

// Set the new bits 
_CrtSetDbgFlag(tmp); 
} 
+0

嗯,有趣。之前没有看到过这种方法。 – Benj

+0

我猜这只适用于CRT内存功能,如malloc/free?我猜测任何使用VirtualAlloc甚至HeapAlloc的东西都不会被检查。 – Benj

+0

你说得对。它是通过堆构建的,它不知道像HeapAlloc或VirtualAlloc这样的“本机”调用 – cprogrammer

3

你有我的同情心:一个非常难以追查的问题。正如你所说的那样,这些通常是在崩溃前一段时间发生的,通常是由于行为不当(例如,写入已删除的内存,运行数组末尾,超过memcpy中分配的内存等) 。我已经使用堆检查工具(valgrind,purify,intel inspector),但正如你所观察到的,这些经常会影响性能,从而掩盖了错误。 (您不会说它是一个多线程应用程序,还是处理诸如传入消息的可变数据集)。

我也重载了新的和删除操作符来检测双删除,但这是一个相当特殊的情况。

如果没有可用的工具帮助,那么你就是你自己的,它将是一个漫长的调试过程。 这个我可以提供的最好的建议是努力减少将重现它的测试场景。然后尝试减少正在执行的代码量,即删除部分功能。最终你们会解决问题,但我已经看到很多好的人花费了6周或更长的时间在大型应用程序(大约150万个LOC)上追踪这些问题。

一切顺利。

+0

该应用程序确实是多线程的,男孩是否有很多线程。它本质上是一个代理进程,它在终端服务盒上为每个会话启动,因此从理论上讲,更多的用户并不意味着更多的负载,而是更少的可用资源。这显然是导致问题的某种类型的并发问题,可能是某个对象的生命周期不正确,并且内存正在写入已释放或某些内存中。哼哼... – Benj

0

您应该进一步阐述你的软件实际上没有。它是多线程的吗?当您谈论“登录到该框的用户数量”时,每个用户是否会在不同的会话中打开不同的软件实例?您的软件是一项Web服务吗?实例是否与对方交谈(如使用命名管道)?

如果您的错误只发生在高负载下,并且在AppVerifier运行时不会发生。我能想到的唯一两种可能性(没有更多信息)是一个并发问题,它与您如何实现多线程相关,或者测试机器有一个硬件问题,只在重负载下出现(让您的测试人员使用多台机器?)。

相关问题