如何在Windows上诊断堆栈损坏错误?

12

我正在使用Windows 8.1 64位和Visual Studio 2013 Ultimate。 我正在将一款使用C ++,OpenGL和SDL的程序从Linux移植到Windows。 我已经通过cmake在64位Windows上自定义编译了适当的库。 当我从Visual Studio运行该程序时,IDE显示有头文件损坏。 这不足为奇,因为我使用指针来实例化对象,并且我正在使用原始指针。为了论点的缘故,我打算稍后使用智能指针进行更改。现在我要做的是boost魔法。

与此同时,我使用我的Linux计算机通过Valgrind检测任何内存泄漏,但没有发现严重问题。 然后我继续使用CppCheck,但也没有发现严重问题。 可能我太宽容了,Windows可能会比Linux更认真地处理一些不太严重的事情,这令人惊讶,因为MSVC通常比GCC更宽容。

所以,该程序在Linux上运行正常,在Windows上却不行(太棒了!)并且Visual Studio通过抛出异常并没有提供帮助,这让我更加讨厌Windows。 我开始在谷歌上寻找解决方案,找到了一个叫做gflags或page helper的工具,于是我安装了调试工具并尝试启动gflags,但我不知道如何使用它! 我后来发现您必须使用另一个名为adp的工具,然后将gflags附加到该工具上,因此当我启动adp时,它就会崩溃。 现在我不知道该怎么办了,即将放弃移植(这很有趣,因为许多人抱怨从Windows到Linux移植程序很难,而相反则是真的)。

所以,现在我向这个社区求助:如何调试/诊断仅在Windows上发生的堆损坏错误? 我真的应该使用gflags还是依靠直觉解决呢?


1
VS具有内置的内存泄漏检测器:https://msdn.microsoft.com/zh-cn/library/x98tx3cf(v=vs.120).aspx - πάντα ῥεῖ
你用过调试器吗?你也可以在Linux上尝试使用clang sanatizers。也许它们能找到valgrind和cpp check没有发现的问题。 - MikeMB
抱歉我有段时间没有回复了。我仍然有这个问题,但似乎是来自一个外部的.dll文件。我不确定是否是我的问题,总之访问冲突0xFF错误很烦人! - Poriferous
在Windows系统中,每个进程都有一个默认的系统堆栈,并且C和C++运行时会在实现malloc和free函数时使用默认的进程堆栈。了解确切的错误消息可以帮助确定检测到问题的层,从而可以缩小调试选项范围。 - Adrian McCarthy
2个回答

16

谢谢您的回复。我从未遇到过这个调试功能,所以很有趣。太棒了! - Poriferous

10

@Carlos的解决方案对于小问题来说是完美的。但是对于大型问题,由此产生的减速有时是难以忍受的。

在这种情况下,可以放置

ASSERT(_CrtCheckMemory()); 

在代码中的某个地方,人们已经怀疑问题已经存在。此命令仅在插入位置检查堆,而不是在每次newdelete调用后都进行检查,如选项_CRTDBG_CHECK_ALWAYS_DF。与选项_CRTDBG_CHECK_ALWAYS_DF相比,这可以保持执行时间的合理性。

通过使用二进制搜索方法来放置断言,可以很快找到有问题的代码行。


然而,有时候 _CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF) 和/或 _CrtCheckMemory() 无法检测问题。那么使用 gflags 是另一种可能性,它能够显示堆破坏发生的位置。简而言之:
  • enable page heap (usually you would need admin's priveleges), e.g.:
    "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe" /p /enable <full_path_to_exe_to_debug.exe> /full 
    
    there will be a report, that heap checks for exe_to_debug.exe were activated.
  • run program in debugger. Accesses out of bounds, which would corrupt the heap lead now to access violation and are easily seen in the the debugger.
  • disable page heap once debugging is done, e.g.:
    "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe" /p /disable <full_path_to_exe_to_debug.exe>
    
  • programs with activated heap check can be listed via
    "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe" /p
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接