如何跟踪仅在调试器下发生的间歇性崩溃,但是没有被它捕获?

时间:2011-08-22 06:36:12

标签: delphi crash c++builder vmware-fusion

我有一个奇怪的间歇性崩溃只在某些情况下发生我无法解决问题,而且我寻求SO的建议来解决它。 < / p>

错误

在显然随机的点上,Windows显示“[App]已停止工作”对话框。它是ntdll.dll中的APPCRASH,异常代码4000001f,异常偏移量000a2562。这就是它变得棘手的地方:只有在调试器下运行应用程序时才会出现这种情况。但是,调试器不会捕获此异常,并且在Windows显示此对话框时,IDE没有响应。正常运行时不会发生此错误,即不在IDE调试器中。

Screenshot of the Windows crash dialog

我无法在调试器外部重现它,所以我无法运行程序并在它已经崩溃时附加。当Windows显示此对话框时,我无法暂停执行,因为IDE没有响应。我可以手动跟踪代码行以查看它出现的位置。有几个,它发生的地方显然是随机的。有一段时间,它在创建一个线程时显示一个窗口(或新表单)一段时间。

编辑:我已将其跟踪到IDE:如果我暂停断点并单击“线程状态”选项卡,程序将立即崩溃,并带有上述对话框即使它在理论上暂停了。在这种情况下,IDE仍然保持响应。这真的很奇怪。

更多信息

我刚将开发环境移至VMWare Fusion。从我的新计算机上的旧(本机Windows)计算机运行构建时,也会发生该错误;它在旧计算机上的相同EXE文件中没有出现。这让我想知道它是否与我的新设置中的Fusion有关。

我正在跑步:

  • OSX Lion 10.7.1上的WMWare Fusion 3.1.3上的Windows 7 Pro x64,全部更新。 Fusion在我的一个屏幕上以“全屏”模式运行。
  • 本地运行Windows 7(不在VM中)的同事不会遇到此问题。我也没在旧的Vista电脑上。
  • Embarcadero RAD Studio 2010,完全更新(我希望;大约有五个更新并且按顺序排列它们很棘手。)我安装了DDevExtensions 2.4.1,以及最新的IDE Fix Pack:卸载这两个都没有效果。
  • 应用程序主要是用C ++编写的,带有Delphi的片段。它是32位。
  • 我们使用EurekaLog,但异常也没有被它捕获。 (通常,调试器首先捕获异常,然后由EurekaLog捕获。)
  • 运行调试版本(没有EurekaLog,额外的调试信息等,调试DCU设置为true)也会重现它。但是,C ++ Builder项目设置对话框的Delphi链接页面上的“调试DCU”选项似乎没有任何效果 - 我无法进入VCL代码并找到实际触发错误的行。
  • Codeguard(检测内存访问错误,双重释放,释放内存中的访问,缓冲区溢出等)不会报告任何内容。

4 个答案:

答案 0 :(得分:8)

这具有内存损坏的所有标志。它仅在您在特定环境下运行时出现,并且每次都出现在不同的位置。两种经典症状。

我知道调试它的最好方法是下载完整的FastMM并在启用完整调试选项的情况下运行。

如果这没有用,那么你就可以逐个删除部分代码,直到你能解决问题为止。

我在D2010中看到的另一个问题是将本地类定义(即类内部类)与泛型混合时出现问题。生成的代码很好,但是调试DCU是错误的,当单步执行代码时,调试器跳转到错误的文件并在不久之后死掉。您似乎没有完全相同的问题,但IDE死亡事件有相似之处。

最后,我建议您怀疑自己的代码而不是VMware。总是很容易责怪其他事情,但根据我的经验,每当我这样做时,最终总是我的代码!

答案 1 :(得分:3)

我遇到了一个非常相似的问题。我也一直在开发.dll,当我在代码中的任何地方设置断点时,Delphi停在源代码行,主机应用程序立即崩溃。

在调试布局中关闭“线程状态窗口”“修复”了问题。 我正在使用Windows 7 64位和Delphi XE3。

答案 2 :(得分:2)

4000001F是STATUS_WX86_BREAKPOINT

换句话说,它是INT 3,它不是由IDE处理的。

由于它是在NTDLL中引发的 - 我猜这表明系统堆中存在内存损坏。请记住,在调试器下运行时,某些Windows代码会switch to debugger version。这就是为什么当应用程序在调试器外独立运行时无法重现这一点的原因 - 因为没有生成断点。

您可以在完全调试模式下尝试FastMM,但我认为它不会对您有所帮助。腐败不会发生在你的记忆中,它发生在系统内存中。是的,也许内存分配方案会被改变 - 你的腐败会在你的代码/内存中显露出来......可能是。尝试使用自上而下的分配,尝试使用SafeMM ...

另一种可能的方法是使用Application Verifier

另见:

答案 3 :(得分:1)

检查项目dsk文件并确保它没有指向错误单元的引用。修复方法是在编辑器中打开dsk并将文件位置更改为正确的位置。