成功关闭应用程序后的 AV

发布于 2025-01-06 22:11:10 字数 416 浏览 4 评论 0原文

在应用程序按预期关闭后大约 3 到 5 秒,我收到此 AV 消息:

Exception EAccessViolation in module rtl160.bpl at 00073225. Access Violation at address 500A3225 in module 'rtl160.bpl'。读取地址 00000004。

这 (20) 个应用程序非常相似,因为它们都是 IBX 业务应用程序。其中大约一半并未导致 AV 的发生。

这些应用程序是从 Delphi-xe 移植的,并且可以完美运行很长时间。港口项目没有发生任何变化。 32 位和 64 位版本都给出了相同的结果。

这是某些库的最终确定部分释放资源或其他内容的错误吗?

我正在使用 Delphi-XE2 Update 3。

非常感谢您的帮助。

I am getting this AV message about 3 to 5 seconds after the applications close as expected:

Exception EAccessViolation in module rtl160.bpl at 00073225. Access violation at address 500A3225 in module 'rtl160.bpl'. Read of address 00000004.

These (20) applications are very similar in that they are IBX business applications. About half of them did not cause the AV to occur.

These applications were ported from Delphi-xe and they worked flawlessly for a long time. No changes were made to the projects in the port. Both 32 and 64 bit builds gave the same results.

Is this a bug in some library's finalization section freeing a resource or something?

I am using Delphi-XE2 Update 3.

Would appreciate the help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

故人爱我别走 2025-01-13 22:11:10

尝试使用 madExcept / EurekaLog 等 - 它们为您提供 AV 上详细的堆栈跟踪。这并不总是万能的,但可以指出问题所在。

Try using madExcept / EurekaLog etc. - they give you detailed stack trace on AV. This is not always a panacea, but can point you to the problem.

做个少女永远怀春 2025-01-13 22:11:10

访问冲突本质上已经是非常麻烦的野兽,因为它们处理内存中的无效指针。应用程序关闭一段时间后发生的情况甚至更糟,因为此时您的应用程序处于“清理”模式。您可能正在处理应用程序中较早出现的错误,但仅在关闭时才暴露出来。

一般提示:

  • 尝试始终按照与执行操作相反的顺序撤消操作。例如
    • 创建 A,创建 B ...销毁 B,销毁 A
    • 连接到数据库,打开数据集...关闭数据集,断开与数据库的连接
  • 即使确保在关闭之前已完成上述所有操作也会有很大帮助。
  • 应用程序运行时仍在运行的任何线程都可能导致问题。
    • 最好确保所有子线程在最终关闭之前正确终止。
    • 请参阅上面的关闭数据集。根据您正在执行的操作,某些数据库组件将创建自己的线程。
  • 如果您使用 COM,请尝试确保 ComObj 在初始化序列中位于较高位置(即,将其放在 DPR 中尽可能高的位置)。
    • Delphi 以与初始化单元相反的顺序完成单元。
    • 并且您不希望 ComObj 在依赖于 ComObj 的其他事物完成之前完成。
  • 如果您使用接口引用,请确保解决循环引用问题。
  • 其中一些问题可能很难发现,但您可以执行以下操作:
    • 设置源代码“沙盒”环境(一旦发现问题,您将放弃所有更改)。
    • 找出保证错误所需的最简单的一组步骤。 (启动应用程序并立即关闭是理想的选择。)
    • 然后,您将在测试之间注释掉删除擦除代码块,并基本上遵循分而治之的方法:
      • 撕掉代码
      • 测试
      • 如果问题仍然存在,请重复。否则回滚并删除不同的代码块。
    • 最终您的代码库将足够小,可以查明可能存在的问题,并可以通过有针对性的测试来解决。

Access Violations are by their nature already very troublesome beasts since they deal with invalid pointers in memory. One that occurs a while after an application shuts down is even worse because that's when your app is in "cleanup" mode. You're could be dealing with something that went wrong much earlier in the application, but is only exposing itself at shutdown.

General Tips:

  • Try to always undo things in the reverse order you did them. E.g.
    • Create A, Create B ... Destroy B, Destroy A
    • Connect to Database, Open Dataset ... Close Dataset, Disconnect from Database
  • Even making sure you've done all the above before shutting down can help tremendously.
  • Any threads that are still running while your application is running can cause problems.
    • Preferably ensure all your child threads are properly terminated before final shutdown.
    • Refer back to Closing datasets above. Depending on what you're doing, some database components will create their own threads.
  • If you're using COM, try ensure ComObj is high up in the initialization sequence (I.e. place it as high as possible in your DPR).
    • Delphi finalizes units in the reverse order that they were initialized.
    • And you don't want ComObj to finalize before other things that are dependent on ComObj have also done so.
  • If you're using interface references, make sure you resolve circular reference issues.
  • Some of these problems can be tricky to find, but you can do the following:
    • Setup a source-code "sandbox" environment (you're going to chuck all your changes as soon as you've found the problem).
    • Figure out the simplest set of steps required to guarantee the error. (Start app and immediately shutdown would be ideal.)
    • Then you're going to comment-out delete wipe out chunks of code between tests and basically follow a divide and conquer approach to:
      • rip out code
      • test
      • if the problem persists, repeat. Else roll-back and rip out a different chunk of code.
    • eventually your code base will be small enough to pinpoint likely problems which can be tackled with targeted testing.
屋檐 2025-01-13 22:11:10

我在旧的 Delphi 或 C++Builder 项目中有时会遇到这种访问冲突问题。今天我用C++Builder 完成了它。崩溃时,通过查看“调试”->“在“调用堆栈”窗口中,我可以看到它发生在对 fflush 的调用中,由 __exit_streams 和 _exit 调用。

我不确定是什么原因造成的,因为它在 Borland 库代码中是如此之深,但当代码更改时它似乎会随机出现和消失。而且它似乎在多形式应用程序中更为常见。

这次,当我刚刚在主窗体上添加了一个新按钮时,错误就消失了。按钮就在那里,没有事件处理程序,也不执行任何操作。我认为,当您重新链接应用程序时,对代码、类、变量等的任何随机更改都会重新排列内存布局,并且会触发或取消触发错误。

现在,我只是将新按钮保留在表单上,​​将其设置为“不可见”,这样就没有可见的更改。因为它似乎有效,所以目前对我来说这是足够好的解决方案。

I've had this kind of access violation problem on occasion with old Delphi or C++Builder projects. Today I had it with C++Builder. At the time of the crash, by looking in the Debug -> Call Stack window, I can see that it's happening inside a call to fflush, called by __exit_streams and _exit.

I'm not sure what is causing it, since it's so deep in the Borland library code, but it seems to come and go at random when the code changes. And it seems to be more common with multi-form applications.

This time the error went away when I just added a new button on the main form. A button which is just there, has no event handlers and does not do anything. I think that any random change to the code, classes, variables etc rearranges the memory layout when you relink the application, and that either triggers or untriggers the error.

For now, I just leave the new button on the form, set it to "not visible" so that there's no visible change. As it seems to work, it's good enough solution for me at this time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文