【问题标题】:Delphi: How can I debug access violations when closing my application?Delphi:关闭应用程序时如何调试访问冲突?
【发布时间】:2011-10-10 16:09:50
【问题描述】:

我正在使用 Delphi 6,并且我有一个应用程序在关闭时会产生访问冲突错误。我们使用 EurekaLog,因此我正在获取堆栈跟踪以进行调试,但错误似乎每次都在不同的单元中随机发生,但总是在 finalization 部分中释放某些内容时发生。

我该如何调试它以查看导致问题的原因?我不确定如何开始调试应用程序完成时发生的事情。

[编辑:] 抱歉,如果我不清楚,也许更好的问题是:如果我只想遍历完成部分,那么用断点开始调试的最佳位置是什么?这些错误似乎出现在我们使用的第三方组件(devexpress dx/cxgrid 库)中,所以我想在 Delphi 开始在其他单元中调用 finalize 例程之前的最后一点开始调试我的代码。

【问题讨论】:

  • 正常调试。如果 AV 出现在 RTL/VCL 单元中,您可能需要使用调试 DCU。在完成部分设置断点并逐步执行。其实你并不需要设置断点,你可以在调试器下运行并安排异常触发断点。
  • FastMM 内存管理器也是跟踪内存泄漏的宝贵工具。 fastmm.
  • 你有很多表格吗?尝试在调用 Application.Run 后从 .dpr 文件中释放它们。看看是否有帮助。如果你让 Application 去做,那么你可能会遇到一些复杂的 VCL 错误(但我不确定它们会延伸到 D6)。
  • @David 您是否有更多信息或有关这些表单破坏错误的链接?我最近调试了一些可能起作用的情况......
  • 我提交了一份质量控制报告。记不住号码。搜索我的名字就能找到。

标签: delphi access-violation


【解决方案1】:

这没什么好说的,但是如果我不得不根据过去的经验猜测...您使用的是包还是 COM 库?如果您有一个作为接口的全局变量,或者是在 BPL 中声明其类的对象,并且您在清理对象/接口之前卸载了 DLL/BPL,您将遇到访问冲突,因为您的代码试图在不再映射到应用程序的地址空间中进行 VMT 查找。

检查并确保在finalization开始之前清理所有此类变量。

【讨论】:

  • 尽管此响应给出了有关哪些更改可能会使问题消失的建议,但它并没有真正回答如何调试的问题。 您使用了哪些技术来确定全局接口变量是问题所在?
  • @Rob:很多设置断点,按 F7 和 F8,并密切关注正在发生的事情。上次我遇到这个问题是在 D2010 上,在他们开始发布系统 DCP 的调试版本之前。不好玩,相信我。
  • @Rob :除了它建议关注什么,我同意 Mason 过去的经验,COM 对象可以对你这样做。
  • @MasonWheeler 谢谢 - 我已经稍微更新了这个问题。在我编写的代码中,我没有使用包或 COM 库,但我使用的可能是第三方组件,我不确定。
【解决方案2】:

当应用程序关闭时,不要释放终结部分的东西。

1) 当应用程序关闭时,Windows 会释放所有应用程序内存。你不必那样做。

2) 当应用程序关闭时,内存被释放,基础设施被卸载。您不能调用代码来关闭或释放对象,因为该代码可能已经被卸载。您无法访问指向内存的指针,因为这些指针可能已被释放。

3) 当您尝试在应用程序关闭时释放终结部分中的内容时,您可能会遇到阻止您的代码终结的故障,从而阻止应用程序关闭,从而导致应用程序挂起和内存丢失。这是您首先要防止的。不要这样做。

好的,当您在 Win95/98 上运行或使用外部进程时,您可能在某些情况下必须释放共享资源并通知那些外部进程您正在关闭。除此之外,这一切现在都是自动发生的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    相关资源
    最近更新 更多