Delphi - 用于跟踪传播访问冲突的工具/技术

时间:2013-06-18 08:33:50

标签: delphi delphi-xe

即使听起来很奇怪,我相信在处理包含大量自定义组件的大型应用程序时,每个人都遇到过这种问题。在某处生成AV,但应用程序继续执行,稍后会引发错误。我不是在谈论多线程应用程序。关于通用单线程应用程序。

我正在努力找到一个随机引发的错误,甚至我正在使用MadExcept / AQT,调试dcus和断点,但我无法确定引发它的步骤,以及引发它的步骤。错误正在传播,并且有时会出现TWinControl destroy(Delphi标准TPageControl),有时打开数据集(使用相同的SQL打开和关闭几次)。所以堆栈被破坏了,在这种情况下我无法使用它。

我知道这个问题过于局部化了,但我问你还有其他替代品来跟踪这类错误。

5 个答案:

答案 0 :(得分:7)

我开始使用其他一些内存管理器来查看是否可以更快地强制破坏应用程序的使用模式。

FastMM可以使用FullDebugMode运行(确保将相应的DLL与您的应用程序EXE一起使用)。它可以做的一些重要事情:

  • 使用模式填充内存(如建议的Arioch 'The
  • 检查块被释放后对块的修改
  • 应用程序终止时记录内存泄漏
  • 回调某些事件,以便您可以记录内容

过去我写了两篇关于FastMM的博客文章,我知道我应该写更多关于它和其他内存管理器的文章。

编辑:有关SO用户Memory Manager Investigations的其他内存管理员Eric Grange的精彩文章。

出于文档目的,其他一些内存管理器(其中大多数不适用于您的案例,但我还没有发现包含所有内容的帖子):

在多线程环境中,这些可能很好:

在EXE / DLL设置中,您可能想尝试FastShareMem

在他的ScaleMM repository中,AndréMussche做了test quite a few other memory managers

注意:+1;好问题,我应该找一些时间写一篇关于Delphi内存管理员的后续博客文章(:

答案 1 :(得分:3)

记录到文件可能会改变结果,因此我建议使用GExperts调试器将消息实时写入输出窗口。编写一个包装函数,以便您可以根据需要转储到文件,控制记录的内容(日志级别过滤器)等。

将记录放入所有单位的初始化/终结中。我发现在最终确定期间经常发生“突然出现”错误。例如:关闭数据库连接,但该对象已被其他东西释放。 D'哦!

还要记录任何组件的事件处理程序,以及这些组件的析构函数。这将显示您是否在组件被销毁后触发事件。

作为最后的手段,您可能必须“删除”程序,删除您编写的所有代码,以“块”。将代码保存在某处,删除form1上的事件处理程序,编译和测试。如果错误消失,请放回事件处理程序并删除其中一半,重新测试。继续,直到你充分缩小范围,并通过消除过程确定罪魁祸首。

答案 2 :(得分:2)

我认为这比德尔菲问题更具普遍性。但是一些有用的技术包括:

  • 过度记录到文件,以便您以后可以使用所有值进行学习
  • 无处不在。您可以禁用它们,以免在发布时添加任何费用
  • 禁用部分应用程序,直到错误停止显示,或
  • 禁用除一些基本shell之外的所有内容,然后逐个启用组件,直到AV返回。
  • 使用ReportMemoryLeaksOnShutdown := true跟踪内存泄漏。

当您找到似乎触发错误的组件时,请进入该步骤并重复此过程,同时禁用其中的所有内容并逐步启用部件。

答案 3 :(得分:2)

有两件事情成了我最好的朋友,尤其是在开发非视觉材料时,不仅仅是在Delphi中:

  • 单元测试和记录

我使用(DUnit)进行单元测试,但也进行系统和压力测试。 我使用AQT来评估单元测试和内存泄漏检测的覆盖范围。 我的想法是,我不需要预先为每个方法编写测试, 但尝试编写尽可能多的测试。 当出现特殊问题时,我会编写一个测试来重现问题 然后我知道我的修复工作的时间。 特别是对于大型应用程序而言,另一个优点是我可以在进行更改后运行测试 并验证一切仍然按预期工作。

我使用的另一个工具是SmartInspect,因为它记录了进入和离开方法, 除此之外,还有一个用于监控现有代码的向导(添加输入离开日志记录)和一个用于过滤日志的控制台。

答案 4 :(得分:2)

奇怪的是,没有人提到称为SafeMM的调试内存管理器。它可以准确地捕捉AV发生的位置。