Visual Studio - 如何查找堆损坏错误的来源

Dan*_*nne 32 debugging heap-memory visual-studio

我想知道是否有一种很好的方法可以找到导致堆损坏错误的源代码,给定在Visual Studio中分配的堆块"外部"写入的数据的内存地址;

专用(0008)免费列表元素26F7F670大小错误(死)

(试着写下关于如何查找内存错误的一些注释)

提前致谢!

And*_*nck 57

从安装windbg开始:

http://www.microsoft.com/whdc/Devtools/Debugging/default.mspx

然后像这样打开pageheap:

gflags.exe –p /enable yourexecutable.exe /full
Run Code Online (Sandbox Code Playgroud)

这将在每次堆分配后插入一个不可写的页面.

从windbg内部启动可执行文件后,此调试器现在将捕获堆外的任何写入.要在之后关闭pageheap,请使用以下命令:

gflags.exe -p /disable yourexecutable.exe
Run Code Online (Sandbox Code Playgroud)

有关如何在此处使用pageheap的更多信息.

  • 最佳方案!救了我的命.另外,直接打开gflags.exe并使用GUI也可以.转到"图像文件",填写exe文件名,然后选中"启用页面堆".任何调试器都可以工作. (5认同)
  • 使用时要非常小心!!!我遇到了设置所有gflag的情况,但后来却忘记禁用它们。我花了整整一周的时间才弄清楚那些标志正在引起下一个问题。 (3认同)
  • 非常感谢。我花了两天时间才发现这项技术。我只是选中“启用页面堆”,然后像往常一样使用Visual Studio调试器。然后,它将完全在代码位置中断,从而导致堆损坏错误。我的错误是由于一个线程持续不断地馈送数据,而另一个线程仅为旧数据分配了足够的内存,而这不足以存储新数据。 (2认同)

Mer*_*avi 7

对于Windows 10,您可以在GFlags工具中启用PageHeap选项,该工具作为Windows调试工具的一部分包含在内。

GFlags中的“页面堆”选项使您可以选择标准堆验证或整页堆验证。请注意,全堆验证会为每个分配使用一整页内存,因此可能导致系统内存不足。

要在GFlags中启用页面堆:

•要启用标准页面堆验证,标准版本将在每个堆分配的末尾编写一个模式,然后在释放分配时检查该模式。

要验证所有过程,请使用:

gflags / r + hpa

gflags / k + hpa

用于单个过程:

gflags / p /启用ImageFileName

•要为一个进程启用全页堆验证,此选项在每个分配的末尾放置一个无法访问的页,以便程序在尝试访问分配之外的内存时立即停止,由于以下原因,该程序仅应在单个进程上使用:大量的内存消耗。

gflags / i ImageFileName + hpa

gflags / p /启用ImageFileName / full

上面的两个命令可以互换。

注意:上面提到的所有页面堆设置都是系统范围的设置,存储在注册表中(/ k除外),并且在您更改它们之前一直有效。/ k设置是为此会话设置的内核标志设置,在Windows关闭时将丢失

另一个有用的工具是应用程序验证程序,但它不是Windows调试工具的一部分,而是包含在Windows软件开发工具包(SDK)中


小智 5

也许你可以尝试一下微软的应用程序验证器。它通过对堆操作进行额外检查,为我解决了一次类似的问题。在我看来,损坏地址的随机性是因为堆可能被“巧妙地”损坏,并且直到堆发生重大事件(例如大量分配/释放)时问题才会出现。


Tim*_*sch 2

您可以在写入内存地址时设置断点。然后,调试器将向您显示写入该位置的代码,但您仍然需要找出哪些写入导致了问题。