delphi - 如何找出哪些代码调用了已经卸载的模块?

标签 delphi debugging delphi-2007 access-violation application-shutdown

我遇到了典型的访问冲突:

access violation at 0x4ebb7456: read of address 0x4ebb7456

这发生在程序的其余部分已经关闭时创建的线程中。

发生异常时主线程正在运行System.FinalizeUnits

我发现该地址属于加载gdiplus.dll的内存区域。

如果我向 dpr 文件添加 LoadLibrary('gdiplus.dll') 调用而不在返回的句柄上调用 FreeLibrary,问题就会消失,这样在运行终结部分时不会卸载 gdiplus.dll

如何找出程序的哪一部分创建了导致访问冲突的线程?

有没有办法识别调用已释放内存空间的代码?

FastMM 和 madExcept 帮助不大,显示 madExcept 错误报告窗口,但立即再次关闭并且不写入日志文件。

我可以将程序拆开,但它是一个不平凡的应用程序,我宁愿使用某种调试技术来解决这个问题。

最佳答案

追踪此问题的第一步可能是检测代码的哪一部分实际创建了线程。在应用程序关闭期间创建线程对我来说听起来就像是坏消息,因此我希望确保这种情况不会发生。

至于如何做到这一点,我会使用调试器断点。首先,我在 Windows.pas 中的 CreateThread 实现上设置断点,并使用调试 DCU 运行。查看该断点是否在关闭期间触发。

如果它在关闭期间没有中断,则该线程是由非 Delphi 代码创建的。我的下一步是打开 CPU View 并进入 CreateThread。 CreateThread 的反汇编将从 JMP 指令开始。进入此页面,您将进入 kernel32.CreateThread。现在在此处设置一个断点,看看当您在关闭期间触发此断点时,调用堆栈是什么。

关于delphi - 如何找出哪些代码调用了已经卸载的模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6899629/

相关文章:

delphi - 在Delphi中调用FormMouseDown

Delphi XE2 服务未正常停止

delphi - 在Delphi XE中设置运行时的onclick事件

ios - 在 iOS/callStackReturnAddresses 和 callStackSymbols 中调试

windows - 如何以编程方式查找两个目录之间的差异

azure - 用于访问 Azure 上的公共(public) RESTServer 应用程序的请求 OAuth2 参数

Python:如何让代码适用于所有失败

arrays - 使用 gdb 时,如何在 Pascal 中打印数组中的部分值

c# - 在 Delphi 2007 中使用 SDK BSOD 但在 C# 中工作的应用程序

delphi - 使用Variant数组在Delphi 2007中需要什么?