如何诊断Windows上的堆损坏错误
How do I diagnose heap corruption errors on Windows?
我使用Windows 8.1 64位和Visual Studio 2013 Ultimate。我正在将一个程序从Linux移植到Windows,它使用c++, OpenGL和SDL。我在64位的Windows上通过cmake自定义编译了适当的库。当我在Visual Studio中运行程序时,IDE说有一个头部损坏。这并不奇怪,因为我正在使用指针来实例化对象,并且我正在使用原始指针,为了参数的缘故,我计划将其更改为智能指针。我稍后会做提升魔法。
在此期间,我用我的Linux电脑通过Valgrind来诊断任何内存泄漏,Valgrind没有报告任何严重的问题。然后我继续使用CppCheck,但那里也没有什么严重的问题。也许我在这里太宽容了,Windows实际上可能比Linux更严肃地对待不那么严肃的事情,这是一个惊喜,因为MSVC往往比GCC更宽容。所以,这个程序可以在Linux上运行,而不能在Windows上运行。(太棒了!)Visual Studio到处抛出异常,这让我更加讨厌Windows。我开始在谷歌上寻找解决方案,并遇到了这个叫做gflags或page helper的东西,所以我安装了调试工具并试图启动gflags,但我不知道如何使用它!后来我发现你必须使用其他一些叫做adp的工具,然后给它附加gflags,所以当我启动adp时,它崩溃了。所以现在我不知道该怎么做,正处于放弃移植的边缘(这很有趣,因为许多人都在抱怨将程序从Windows移植到Linux是多么困难,而事实恰恰相反)。
所以,现在我呼吁这个社区的帮助:我如何调试/诊断堆损坏错误发生在Windows上,而不是在Linux上?我真的应该使用gflags吗?还是我应该在这个问题上使用我的直觉?
使用调试堆并在main()的最开始调用它。
_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF);
它会使程序慢很多,但是一旦发生损坏,它应该会崩溃。
详细信息请参阅本文:https://msdn.microsoft.com/en-us/library/974tc9t1.aspx#BKMK_Check_for_heap_integrity_and_memory_leaks
@Carlos的解决方案对于小问题来说是完美的。但对于大问题,由此导致的速度放缓有时是你无法忍受的。
在这种情况下,可以放置
ASSERT(_CrtCheckMemory());
在代码的某个地方,人们怀疑问题已经存在。该命令在(且仅在)插入堆的位置检查堆,而不是像_CRTDBG_CHECK_ALWAYS_DF
那样在每次new
或delete
调用之后检查堆。与选项_CRTDBG_CHECK_ALWAYS_DF
相比,这使执行时间保持合理。
通过使用二进制搜索的方法来放置断言,可以很快地找到有问题的代码行。
然而,有时_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF)
和/或_CrtCheckMemory()
无法检测到问题。然后使用gflags
是另一种可能性,它能够显示堆损坏发生的位置。简而言之:
- 启用页面堆(通常你需要admin的权限),例如:
会有一个报告,"C:Program Files (x86)Windows Kits10Debuggersx64gflags.exe" /p /enable <full_path_to_exe_to_debug.exe> /full
exe_to_debug.exe
的堆检查被激活了。 - 在调试器中运行程序。越界访问会破坏堆,这会导致访问冲突,并且很容易在调试器中看到。
- 在调试完成后禁用页面堆,例如:
"C:Program Files (x86)Windows Kits10Debuggersx64gflags.exe" /p /disable <full_path_to_exe_to_debug.exe>
具有激活堆检查的 - 程序可以通过列表列出
"C:Program Files (x86)Windows Kits10Debuggersx64gflags.exe" /p
- 在C++中检测到堆损坏错误
- AMQP-CPP:TCP 处理程序中的管道损坏错误
- 与强制转换相关的堆损坏错误
- 如何修复C ++中的"堆已损坏"错误?
- 双重释放或损坏错误(找不到错误?
- 对于我的类函数,我得到双重释放或损坏错误
- 为什么我的作业操作员给出了损坏错误
- 为什么 delete[] 会导致堆损坏错误
- 为什么我的visual c++在堆栈损坏的情况下没有触发堆栈损坏错误
- c++运行程序时出现堆已损坏错误
- 范围末尾的C 双免费或损坏错误
- Vector访问中出现内存损坏错误
- C 双免费或损坏错误
- 包含链接列表的链接列表给出了堆的损坏错误:原因
- 在Windows上立即检测到堆损坏错误.如何
- 双重释放或损坏错误
- 使用删除 [] 和新(放置)运算符的可视C++堆损坏错误
- 调试 MS VC++ 2005 中的堆损坏错误
- 堆损坏错误;无法发布 cv::Mat opencv
- 使用auto_ptr时出现内存损坏错误