15

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

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

所以,我们不能使用 Page Heap。添加哪些其他标志会很有用,这样我们要么

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

我们目前正在尝试这些标志:

希望下一个故障转储将包含更多有关问题所在的信息。

我考虑了这些标志,但现在将它们排除在外:

我(也)遇到的一个问题是我不确定这些标志在发生内存损坏时如何提供帮助。当有东西写入保护页时,Page Heap 显然会产生访问冲突,但是其他标志如何操作?

我是否必须使用 Application Verifier 运行应用程序才能获得这些其他标志的帮助?或者当检查代码检测到某些东西时会引发异常?

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


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

4

2 回答 2

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]*
于 2013-09-26T13:19:09.180 回答
1
  1. 恕我直言,控制所有这些检查的最简单方法是使用 ApplicationVerifier。你有一个完美的用户界面,你可以玩所有的标志。
  2. 无堆检查是一个很好的标志,没有太多开销。因此,如果堆块被严重修改并且块被释放,那么您将中断调试器。如果损坏发生在块的分配和释放附近,这可能会有所帮助。
  3. AFAIK“堆参数检查”只是一个轻量级的“调用堆验证”。我从来没有在这方面取得任何成功。
  4. 堆尾检查和标记既简单又快速。有时对我有用。

您知道您也可以使用 gflags 在每个应用程序库上控制它。

gflags.exe /i Testapp.exe e0

但是:找到此类问题的最佳方法是完全使用 Debug-CRT ...如果可能的话。因此,如果有机会在生产环境中使用您的 Debug-Version,那就去做吧。在 Debug-CRT 中,您又可以使用和设置许多标志......

于 2013-09-26T13:28:48.943 回答