GFlags设置捕捉堆损坏(页面堆除外)?

在一个生产站点,我们的应用程序(*)反复崩溃,但不可重复。 分析崩溃转储清楚地表明,这是一个堆腐败:崩溃是在不同的位置,但总是访问ntdll!RtlpLowFragHeapFree kernel32!HeapFree / ntdll!RtlpLowFragHeapFree 。 赢得Dbg !analyze -v也报告堆腐败。

我们迄今为止所尝试的是使用GFlags选项Page Heap来运行应用程序。 问题是页堆的内存开销是这样的,应用程序将不再运行(达到32位进程的虚拟内存限制)。

所以, 我们不能使用Page Heap 。 哪些其他的标志将是有用的添加,以便我们要么

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

我们正在尝试标志:

  • 启用堆标记
  • 启用堆尾检查

希望下一次故障转储能够包含更多的错误信息。

我考虑过这些标志,但是现在就把它们留下了:

  • 启用堆参数检查 …当系统每次调用堆函数时,我都会期待一些开销
  • 启用堆检查 …不知道这是否真的会给我买东西
  • 在通话中启用堆validation …即使文档警告高开销

我(也)有一个问题是,我不确定这些标志如何帮助发生内存损坏。 页面堆显然会产生访问冲突,当一些东西写入到警卫页面,但其他标志如何操作?

我是否必须使用Application Verifier来运行这些其他标志的帮助? 或者当检查代码检测到什么时会引发exception?

这些标志的哪个组合最有意义,这样应用程序仍然可以在生产中正常运行并消耗内存。


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

  1. 恕我直言,控制所有这些检查最简单的方法是使用ApplicationVerifier。 你有一个完美的用户界面,你可以玩所有的旗帜。
  2. 堆空闲检查是一个好标志,没有太多的开销。 所以,如果堆块被严重修改,并且块被释放,那么你可以进入调试器。 如果在分配和释放块附近发生腐败,这可能会有所帮助。
  3. AFAIK“堆参数chechking”只是一个轻量级的“调用堆确认”。 我从来没有任何成功与此。
  4. 堆尾检查和标记是容易和快速的。 有时为我工作。

你知道你可以用gflags来控制每个应用程序的基础。

gflags.exe /我Testapp.exe e0

但是:找到这样的问题的最好方法是完全使用Debug-CRT …如果可能的话。 因此,如果有机会在生产环境中使用Debug-Version,请执行此操作。 在Debug-CRT里面你可以使用和设置很多标志….

gflags图形用户界面中的“启用页面堆”可以实现页堆验证,这可能会导致您描述的问题。 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]*