我们有一个在 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 行,在
{$IFDEF CPUX86}
汇编部分procedure Move(const Source; 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