如何在现场调试Access违规?

时间:2010-12-27 03:04:26

标签: delphi

该领域的应用程序间歇性地收到此消息:

alt text

我无法在我的机器上重现这一点。我还跟踪了我认为相关的代码,无法找到任何未初始化对象的访问权。

我从来没有处理过这种问题。

我使用madExcept进行了构建,不幸的是,程序捆绑后不会崩溃。

有关madExcept和EurekaLog发现此类事情的任何意见吗?我从未使用过FastMM。它会对他的情况有用吗? (Delphi 2010)在FastMM中设置的任何建议标志?还有其他建议吗?

3 个答案:

答案 0 :(得分:12)

请注意您尝试阅读的地址非常低。这种错误几乎肯定意味着你试图取消引用nil指针,即使你找不到它。

鉴于你对行为的描述,我怀疑你有一个内存踩踏 - 有些东西在指向对象的指针顶部爆破零。当你改变东西时,你会移动东西,并且踩踏动作会变得无害。

启用范围检查和溢出检查。

请注意,违规对象的大小必须至少为3C0字节 - 这应该有助于缩小范围,大多数对象都会小于此。

我过去所做的只是在场中显示的错误是将记录检查点放入 - 一串显示某些东西的行 - 一个简单的数字序列就可以了。找出崩溃时显示的数字,并且您知道哪些检查点是最后执行的。如果这不能缩小到足够的范围,你可以重复这个过程,因为你已经缩小了它。

答案 1 :(得分:5)

使用完整的地图文件,您可以识别代码中发生这种情况的确切位置。我希望你有一个完整的图像文件!从引发异常的地址(在您的情况下为$ 007ADE8B)中减去$ 00401000,这与地图文件中的值相对应。

完成后你知道哪个对象是零,从那里通常不会很难弄清楚发生了什么。

最常见的一种方法是构造函数引发异常。发生这种情况时,析构函数会运行。如果你在析构函数中访问一个尚未初始化的字段,并且除了调用Free之外还执行任何操作,那么你将得到这样的异常。

答案 2 :(得分:3)

看起来像内存覆盖,改变内存布局(你的机器与现场机器或添加madExcept)会使覆盖变化变得无害。

FastMM非常善于使这类问题更加一致(并找到它们的来源)。下载FastMM的完整版本,将其添加为项目的第一个单元,并在其设置上启用FullDebugMode。

这可能会导致问题在您的机器中立即重现。如果没有,请不要忘记将FastMM_FullDebugMode.dll与您的应用程序一起部署进行测试。保持madExcept并让它嵌入.map文件用于调用堆栈。