GFlags设置为捕获堆损坏(除了页面堆)?

Mar*_* Ba 11 windows windbg visual-c++ gflags heap-corruption

在一个生产站点上,我们的应用程序(*)反复崩溃,但不可重现.分析崩溃转储清楚地表明它是一个堆损坏:崩溃位于不同的位置,但始终访问kernel32!HeapFree/ 内部的违规ntdll!RtlpLowFragHeapFree.Win Dbg !analyze -v还报告堆损坏.

到目前为止我们尝试的是使用GFlags选项Page Heap运行应用程序.问题是页面堆的内存开销使应用程序不再运行(达到32位进程的虚拟内存限制).

所以,我们不能使用Page Heap.添加哪些其他标志对我们要么有用

  • 在腐败网站上崩溃
  • 或者至少可以从崩溃转储中获取更多信息,这些信息最终将在我们崩溃时生成HeapFree

我们正在尝试标志:

希望下一个崩溃转储包含更多关于出错的信息.

我考虑过这些标志,但暂时将它们排除在外:

我(也)遇到的一个问题是,我不确定这些标志在发生内存损坏时如何起作用.当某些内容写入保护页面时,页面堆显然会产生访问冲突,但其他标志如何运行?

我是否必须使用Application Verifier运行应用程序以获取其他标志以帮助您?或者在检查代码检测到某些内容时会引发异常?

这些标志的哪种组合最有意义,以便应用程序仍可以在生产中以良好的性能和内存消耗运行?


(*):它是工业自动化中的32位Windows桌面应用程序.在这种情况下运行在Win7 64bit上(它在许多其他站点上运行得很好).

Mar*_*man 7

gflags GUI中的"启用页面堆"启用了页堆验证,这可能会导致您描述的问题.gflags命令行为您提供了更多控制,并允许您启用标准页堆验证,该验证使用较少的内存但功能较弱.命令行还使您能够使用/ size,/ dlls和/ address选项使用标准和完整的混合.

以下是debugger.chm帮助文件中列出的选项:

*To enable and configure page heap verification:

    gflags /p /enable ImageFile  [ /full [/backwards] | /random Probability | /size SizeStart SizeEnd | /address AddressStart AddressEnd | /dlls DLL [DLL...] ]  [/debug ["DebuggerCommand"] | /kdebug] [/unaligned] [/notraces] [/fault Rate [TimeOut]] [/leaks] [/protect] [/no_sync] [/no_lock_checks]*
Run Code Online (Sandbox Code Playgroud)


xMR*_*MRi 1

  1. 恕我直言,控制所有这些检查的最简单方法是使用 ApplicationVerifier。您拥有完美的用户界面,并且可以使用所有标志。
  2. 堆免费检查是一个很好的标志,没有太多的开销。因此,如果堆块被严重修改并且该块被释放,您将进入调试器。如果损坏发生在块的分配和释放附近,这可能会有所帮助。
  3. AFAIK“堆参数检查”只是一个轻量级的“调用堆验证”。我在这方面从未取得过任何成功。
  4. 堆尾检查和标记既简单又快速。有时对我有用。

您知道您也可以使用 gflags 在每个应用程序基础上进行控制。

gflags.exe /i Testapp.exe e0

但是:发现此类问题的最佳方法是完全使用 Debug-CRT...如果可能的话。因此,如果有机会在生产环境中使用调试版本,那就去做吧。在 Debug-CRT 中,您再次可以使用和设置很多标志......