delphi - 从 D2006 移植到 XE5 后偶发的访问冲突在 XP 兼容模式下不会发生

标签 delphi windows-7 access-violation delphi-xe5

我们有一个大型应用程序,在 Delphi 2006 中运行良好。我们已将其移至 XE5,但经常遇到偶发的访问冲突。我们使用 VCL 表单和许多 DevExpress 以及其他第三方组件。我们正在使用 Windows 7 Professional 和 Delphi XE Enterprise,版本 19.0.14356.6604。

我们在此处和其他地方在线查找了有关移植到 XE5 后的 A/V 的帖子,但没有找到任何与我们的问题相关的内容。

以下是我们对 A/V 的了解:

  • 它们通常出现在同一地址:0x50059f27。有时它们发生在 0x5005eb86,通常是在其他地址已触发 A/V 之后。
  • 它们发生在应用中的不同位置和操作中。
  • 它们并非 100% 可重现。有时,项目的重建会消除一个触发因素,但随后其他因素会触发它。它们似乎在构建中保持相当一致的可复制性。
  • 它们通常与打开对话框或激活返回大量记录(1,000 条以上)的查询相关。
  • D2006 版本(我们在 XP 机器或 XP 虚拟机上运行)不会发生这种情况。 - 当我们在 XP-SP3 兼容模式下运行 XE5 应用程序时,不会发生这种情况。
  • 如果我们在典型的 A/V 之后中断,指针将位于 System.pas 的第 562 行,位于 procedure Move(const Source) 的 {$IFDEF CPUX86} asm 部分中; var Dest; Count: NativeInt); 该部分代码附加在下面。该行是FILD QWORD PTR [EAX] {Last 8}

我们猜测该问题与我们的应用处理 Windows 7 内存管理的方式有关,但我们不知道如何找出问题所在。附加了示例调用堆栈。

有人可以建议我们如何解决这个问题吗?是否有第三方调试工具可以提供帮助?我们可以使用 Delphi IDE 工具来尝试追踪这个问题吗?可能有用的文章?

非常感谢您的建议。

这是出现 A/V 的 System.pas 代码部分:

    @@LargeForwardMove: {4-Byte Aligned}
    PUSH    EDX
    FILD    QWORD PTR [EAX] {First 8}
    LEA     EAX, [EAX+ECX-8]
    LEA     ECX, [ECX+EDX-8]
    FILD    QWORD PTR [EAX] {Last 8}      // <- Debug break pointer will be here. 
    PUSH    ECX
    NEG     ECX
    AND     EDX, -8 {8-Byte Align Writes}
    LEA     ECX, [ECX+EDX+8]
    POP     EDX

这是调用堆栈的示例:

vcl.Vcl.Buttons.TBitBtn.Click
vcl.Vcl.StdCtrls.TCustomButton.CNCommand(???)
vcl.Vcl.Controls.TControl.WndProc((48401, 3186, 724082, 0, 3186, 0, (), 3186, 11, (), 0, 0, ()))
vcl.Vcl.Controls.TWinControl.WndProc((48401, 3186, 724082, 0, 3186, 0, (), 3186, 11, (), 0, 0, ()))
vcl.Vcl.StdCtrls.TButtonControl.WndProc((48401, 3186, 724082, 0, 3186, 0, (), 3186, 11, (), 0, 0, ()))
vcl.Vcl.Controls.TControl.Perform(???,???,724082)
vcl.Vcl.Controls.DoControlMsg(???,(no value))
vcl.Vcl.Controls.TWinControl.WMCommand((273, (), 3186, 0, (), 724082, 0))
vcl.Vcl.Controls.TControl.WndProc((273, 3186, 724082, 0, 3186, 0, (), 3186, 11, (), 0, 0, ()))
vcl.Vcl.Controls.TWinControl.WndProc((273, 3186, 724082, 0, 3186, 0, (), 3186, 11, (), 0, 0, ()))
vcl.Vcl.Controls.TWinControl.MainWndProc(???)
rtl.System.Classes.StdWndProc(987008,273,3186,724082)
:772462fa ; C:\Windows\syswow64\USER32.dll
:77246d3a USER32.GetThreadDesktop + 0xd7
:77246de8 ; C:\Windows\syswow64\USER32.dll
:77246e44 ; C:\Windows\syswow64\USER32.dll
:77ad010a ntdll.KiUserCallbackDispatcher + 0x2e
:772496c5 USER32.SendMessageW + 0x4c
:75184601 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
:75184663 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
:751844ed ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
:772462fa ; C:\Windows\syswow64\USER32.dll
:77246d3a USER32.GetThreadDesktop + 0xd7
:77250d27 USER32.GetClientRect + 0xc5
:77250d4d USER32.CallWindowProcW + 0x1b
vcl.Vcl.Controls.TWinControl.DefaultHandler(???)
:5046777f TWinControl.DefaultHandler + $EB
:5046766e TWinControl.WndProc + $5CA
:50487a69 TButtonControl.WndProc + $71
:501749c6 StdWndProc + $E
:772462fa ; C:\Windows\syswow64\USER32.dll
:77246d3a USER32.GetThreadDesktop + 0xd7
:772477c4 ; C:\Windows\syswow64\USER32.dll
:7724788a USER32.DispatchMessageW + 0xf

最佳答案

这看起来像是程序中的一个简单错误。释放后可能会访问内存。或者缓冲区溢出。您需要做的是一些调试。您需要的工具是:

  1. 已启用范围检查编译器选项。这会发现大多数缓冲区溢出。
  2. FastMM 完整版,具有完整的调试设置。这应该可以查明诸如释放后访问之类的错误。
  3. 疯狂异常(exception)。这将提供异常点的堆栈跟踪。这很重要,因为它可以让您了解如何在代码中达到这一点。这反过来可以帮助您查看正在传递哪些数据,并为您提供有关您做错了什么的线索。我知道你有堆栈跟踪,但它看起来不正确。毕竟,TBitBtn.Click 不会直接调用Move

不要自欺欺人地认为,您在 XP 上没有看到错误的事实在某种程度上意味着责任在于操作系统。或者您需要在不同版本的操作系统中以不同的方式处理内存。许多应用程序编程错误在某些系统上是良性的,但在其他系统上却很明显。你的程序到处都被破坏的可能性很高,但有时你却侥幸逃脱了惩罚。

关于delphi - 从 D2006 移植到 XE5 后偶发的访问冲突在 XP 兼容模式下不会发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22885790/

相关文章:

delphi - Delphi中如何从URL获取图像

delphi - 接口(interface)和属性可见性

c# - 获取 Windows 7 中语言栏的当前所选语言

c++ - 使用静态 std::vector 类成员时发生访问冲突

c# - 尝试在 C# 中创建基本编译器,获取访问冲突错误

visual-studio-2010 - 应用程序在 Visual Studio 中崩溃,但仅在设置断点之后

delphi - TIdHTTP 组件可以处理 javascript 代码吗?

delphi - 如何更改标签的dragmode属性(firemonkey)

java - 无法找到或加载主类 org.junit.runner.JUnitCore

windows-7 - 无法从命令行使用 telnet 获取 http 响应