Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么';查找仅在性能测试下发生的堆损坏的最佳方法是什么?_C++_Windows_Heap_Windbg_Heap Memory - Fatal编程技术网

C++ 什么';查找仅在性能测试下发生的堆损坏的最佳方法是什么?

C++ 什么';查找仅在性能测试下发生的堆损坏的最佳方法是什么?,c++,windows,heap,windbg,heap-memory,C++,Windows,Heap,Windbg,Heap Memory,我工作的软件(用C++编写)目前存在堆损坏问题。当登录到box的用户数达到某个阈值时,我们的性能测试团队会不断出现WER故障,但他们给我的转储只显示了不重要区域的损坏(例如,当std::string释放其底层内存时) 我尝试过使用Appverifier,但确实出现了一些问题,我现在已经解决了。然而,我现在的情况是,测试人员可以使用Appverifier尽可能多地加载机器,并进行干净的运行,但在没有Appverifier的情况下运行时仍然会出现堆损坏(我猜,因为他们可以在没有Appverifier

我工作的软件(用C++编写)目前存在堆损坏问题。当登录到box的用户数达到某个阈值时,我们的性能测试团队会不断出现WER故障,但他们给我的转储只显示了不重要区域的损坏(例如,当std::string释放其底层内存时)

我尝试过使用Appverifier,但确实出现了一些问题,我现在已经解决了。然而,我现在的情况是,测试人员可以使用Appverifier尽可能多地加载机器,并进行干净的运行,但在没有Appverifier的情况下运行时仍然会出现堆损坏(我猜,因为他们可以在没有Appverifier的情况下在etc上获得更多用户)。这意味着我一直无法得到一个真正显示问题的转储


有没有人对我可以使用的有用技术或技术有其他想法?我已经在没有appverifier的情况下对堆损坏转储进行了尽可能多的分析,但我看不到任何常见的主题。没有线程在崩溃的同时做任何有趣的事情,崩溃的线程是无辜的,这让我觉得腐败发生在前一段时间。

我很同情你:一个很难追踪的问题

正如您所说,通常情况下,这些情况发生在崩溃之前的某个时间,通常是由于写入行为不当(例如写入已删除的内存、运行数组末尾、超出memcpy中分配的内存等)造成的

在过去(在Linux上,我猜想您是在Windows上),我使用过堆检查工具(valgrind、purify、intel inspector),但正如您所观察到的,这些工具通常会影响性能,从而掩盖错误。(你不能说它是一个多线程的应用程序,还是处理一个可变的数据集,比如传入的消息)

我还重载了new和delete操作符来检测双重删除,但这是一种非常特殊的情况

如果没有可用的工具可以帮助您,那么您就只能靠自己了,这将是一个漫长的调试过程。 对于这一点,我能提供的最好建议是减少将重现它的测试场景。然后尝试减少执行的代码量,即删除部分功能。最终你会关注这个问题,但我看到一些非常优秀的人花了6周或更长时间在一个大型应用程序(大约150万LOC)上跟踪这些问题


最好的。

最好的工具是Appverifier与gFlags的结合,但还有许多其他解决方案可能会有所帮助

例如,您可以使用以下代码每16次malloc、realloc、free和_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);
}
#包括
int main()
{
int tmp;
//获取当前位
tmp=_CRTSETDBG标志(_CRTDBG_报告_标志);
//清除所需频率的高16位和或
tmp=(tmp&0x0000FFFF)| CRTDBG_检查_每16_DF;
//设置新的位
_CRTSETDBGSFLAG(tmp);
}

您应该进一步详细说明软件的实际功能。它是多线程的吗?当您谈到“登录到该框的用户数”时,每个用户是否在不同的会话中打开不同的软件实例?您的软件是web服务吗?实例是否相互对话(如使用命名管道)


如果您的错误仅在高负载时发生,并且在AppVerifier运行时未发生。我能想到的仅有两种可能性(没有更多信息)是您如何实现多线程的并发问题,或者测试机器存在仅在重载情况下才会出现的硬件问题(您的测试人员是否使用了多台机器?)。

您的代码是否可以在*nix上移植?如果是这样,启动
valgrind
(或者在Windows上找到一个类似的工具):通常第一次抱怨“无效读取”或“无效写入”是一个很好的提示,说明真正的错误在哪里。啊,如果是:-)我以前使用过valgrind,这是一个很好的工具。Appverifier通常也很方便,但在这种情况下,它对我不起作用:-(另一个上(有些类似)问题,我建议将electric fence移植到windows。它会故意在大量内存错误上对您的程序进行故障隔离,但我不确定它是否有助于解决您所面临的确切问题。您使用analyze识别了堆损坏?!analyze显示了因访问冲突而出现故障的线程,但很明显这是堆损坏原因线程当前运行的代码不可能导致转储显示的情况。!analyze不能真正帮助您解决堆损坏问题。很遗憾,很有趣。以前没有见过这种方法。我猜这只适用于诸如malloc/free之类的CRT内存函数?我猜使用Virtual的任何东西lAlloc甚至可能是HeapAlloc都不会被检查。你是对的。它是在堆上构建的,不知道“本机”像HeapAlloc或VirtualAllocy这样的电话你会很高兴知道我最终发现了问题。虽然我很高兴知道这一点,但我最终并没有使用这种技术。我发现appverfier的问题是在我的产品配置出现问题之后,直到它变得非常极端,在负载较少的情况下才出现。我要标记这是接受答案,因为它是应用验证程序唯一有趣的替代方案。该应用程序确实是多线程的,而且boy确实有很多线程。它本质上是一个代理进程,在终端服务盒上的每个会话都会启动,所以理论上更多的用户并不意味着更多的负载,只是可用资源更少。这显然是某种类型的由于导致问题的并发性问题,可能某个对象的生命周期在某个地方不正确,并且正在写入已释放的内存或类似的内容。呵呵。。。