如何调试仅在应用程序关闭时发生的崩溃? (德尔福)

问题描述 投票:0回答:7

因此,经过最近的一些更改,我们发现我们最古老的应用程序之一有时会在关闭时崩溃。这会以“运行时错误 216”消息的形式或来自 Windows 错误报告的消息的形式表明应用程序已停止工作。该应用程序已经在每次发出

OutputDebugString
消息,并且相信我们自己的所有代码都已正确执行完成。所有析构函数都像所有终结部分和类析构函数一样被调用,它们都不会引发任何异常。

此外,madExcept 和 FastMM4 的完全调试模式似乎都没有什么可抱怨的(尽管这可能是一个错误的结论,因为崩溃甚至可能在这些组件自己的最终代码运行之前发生)。

那么,你会怎么做?你会从哪里开始?


这个问题应该更多地涉及此类问题的一般方法,而不是我当前面临的具体实例,因此我故意省略了细节。请随意询问您是否认为它们可能与调试方法的选择相关,我稍后会添加它们。

delphi debugging crash application-shutdown
7个回答
12
投票

运行时错误 216 意味着您遇到了 Av(访问冲突),并且 SysUtils 已经停止将这些错误转换为异常。

第一次尝试:使用调试 DCU 进行构建,并查看引发错误的单元系统,在那里设置断点。希望您可以在调试器中捕获它并从那里开始工作。

您可能有内存错误(悬空指针、空引用等在已最终确定的单元中使用 s 字符串常量),最好的技巧是在 sysutils 确定后检查最终确定。您可以通过使用调试 dcu 进行构建、将断点设置为 sysutils 中的终结点并开始单步执行代码直到发生错误来完成此操作。


5
投票

您使用运行时包吗?我以前见过类似的问题。如果您跨包边界共享全局变量或接口,则必须确保在卸载该包之前清除对属于某个包的类的所有引用;否则他们会尝试对不再有效的内存进行虚拟调用。


3
投票

好吧,运行时错误 216 是内存问题(访问冲突),看起来您引用了某个当时不存在的对象。

Emarcadero 写道:

使用 SysUtils 类的应用程序将大多数运行时错误映射到异常,这允许您的应用程序在不终止的情况下解决错误

您是否尝试在 Sysutils 的终结部分设置断点?

我会尝试使用分配/内存分析器,它不确定您是否会找到错误代码行,但这可能会向您显示代码中发生内存问题的某些部分。


2
投票

您可能遇到了指针问题。某些事件或方法试图在不再存在的对象上运行。


2
投票

“运行时错误216”来自Windows本身,而不是Delphi异常处理程序。我发现它是由在单元的初始化和终结部分运行的代码引起的,这些代码在 Delphi 异常处理程序启动之前执行。特别是。需要通过 Delphi 应用程序终止后运行的终结代码卸载的 COM 对象将导致此错误和类似错误。所以检查一下那些东西。

MNG


2
投票

就像其他人说的:216表示SysUtils关闭后的AV。通常,在 SysUtils 之后关闭的唯一东西(并且有机会提高 AV) - 是系统单元。具体来说:内存管理器。

因此,关闭时的运行时错误 216 通常意味着应用程序中存在内存损坏错误。

这很容易解决 - 只需在内存管理器中启用完全调试模式或使用调试内存管理器即可。然而,有时可能很难找到。不过你可以先从MM的debug模式开始

请参阅这篇文章


0
投票

旧线程,但实际问题。 我的解决方案是将

Application.MainForm.Free;
添加到主/主窗体的 FormDestroy 过程中,以消除关闭时的错误。 尝试使用“MainForm”而不是您的表单名称。只有这个对我有用。 也许这也可以帮助某人。

© www.soinside.com 2019 - 2024. All rights reserved.