从D2006移植到XE5之后的零星访问冲突在XP兼容模式下不会发生 [英] Sporadic Access Violation after porting from D2006 to XE5, doesn't happen in XP compatibility mode

查看:86
本文介绍了从D2006移植到XE5之后的零星访问冲突在XP兼容模式下不会发生的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have a large application that works fine in Delphi 2006. We've moved it to XE5 and are experiencing frequent sporadic Access Violations. We're using VCL forms and a number of DevExpress and other third party components. We're working in Windows 7 Professional with Delphi XE Enterprise, Version 19.0.14356.6604.

在迁移到XE5之后,我们已经在网上和其他地方寻找有关A/V的帖子,但没有发现与我们的问题有关的任何内容.

We've looked on line, here and elsewhere, for postings about A/Vs after porting to XE5 but haven't found anything that seems relevant to our problem.

这是我们对A/V的了解:

Here's what we know about the A/Vs:

  • 它们通常出现在同一地址:0x50059f27.有时,它们发生在0x5005eb86,通常是在另一个地址已经触发了A/V之后.
  • 它们发生在应用程序中的不同位置和动作中.
  • 它们不是100%可复制的.有时,项目的重建会消除一个触发因素,但其他因素会触发它.它们似乎在构建中保持相当一致的可复制性.
  • 它们通常与打开对话框或激活返回大量记录(超过1000条)的查询有关.
  • D2006版本(我们在XP机器或XP虚拟机上运行)不会发生这种情况. -当我们以XP-SP3兼容模式运行XE5应用程序时,它们不会发生.
  • 如果我们在典型的A/V之后中断,则指针将位于562行的System.pas中,位于procedure Move(const Source; var Dest; Count: NativeInt);{$IFDEF CPUX86} asm部分中.代码部分附在下面.该行是FILD QWORD PTR [EAX] {Last 8}.
  • They usually occur at the same address: 0x50059f27. Sometimes they happen at 0x5005eb86, usually after an A/V has already been triggered at the other address.
  • They happen from various different locations and actions in the app.
  • They aren't 100% reproducible. Sometimes a rebuild of the project will eliminate one trigger but then something else will trigger it. They seem to stay fairly consistently reproducible within builds.
  • They are generally connected with either opening a dialog or activating a query that returns a substantial number of records (1,000+).
  • They don't happen with the D2006 version (which we run on XP boxes or in an XP Virtual Machine). - They don't happen when we run the XE5 application in XP-SP3 compatibility mode.
  • If we break after a typical A/V, the pointer will be in System.pas at Line 562, in the {$IFDEF CPUX86} asm section of procedure Move(const Source; var Dest; Count: NativeInt); The section of code is appended below. The line is FILD QWORD PTR [EAX] {Last 8}.

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

We're guessing that the issue has to do with how our app deals with Windows 7 memory management but we don't know how to figure out where it's going wrong. A sample call stack is appended.

有人可以建议我们如何继续解决此问题吗?是否有第三方调试工具会有所帮助?有没有我们可以用来追踪的Delphi IDE工具?可能有用的文章?

Can anyone suggest how we might proceed to troubleshoot this problem? Are there third-party debugging tools that would help? Are there Delphi IDE tools we can be using to try to track this down? Articles that might be useful?

非常感谢您的任何建议.

Many thanks for any suggestions.

这是在其中发生A/V的System.pas代码部分:

Here's the section of System.pas code where the A/Vs occur:

    @@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

这是调用堆栈中的一个示例:

And here's a sample from the Call Stack:

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

推荐答案

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

That looks like a simple bug in your program. Possibly accessing memory after release. Or a buffer overrun. What you need to do is some debugging. The tools you need are:

  1. 启用范围检查编译器选项.这会发现大多数缓冲区溢出.
  2. FastMM完整版,带有完整的调试设置.这应该指出错误,例如免费后访问.
  3. madExcept.这将在异常发生时提供堆栈跟踪.这很关键,因为它可以让您了解如何在代码中达到这一点.反过来,这可以帮助您查看正在传递的数据,并应该为您提供了有关做错了什么的线索.我知道您有堆栈跟踪,但看起来不正确.毕竟,TBitBtn.Click不会直接调用Move.
  1. Range checking compiler option enabled. This finds most buffer overruns.
  2. FastMM full version with full debug settings. This should pin-point errors like access after free.
  3. madExcept. This will provide stack traces at the point of the exception. That's crucial because it lets you see how you got to this point in the code. That in turn helps you see what data is being passed and should give you clues as to what you've done wrong. I know you have a stack trace but it doesn't look right. After all, TBitBtn.Click does not call Move directly.

不要自欺欺人,因为您没有在XP上看到故障这一事实意味着责任归咎于操作系统.或者,您需要以某种方式在不同版本的OS中以不同方式处理内存.在某些系统上,很多应用程序编程错误是良性的,而在其他系统上则明显.程序到处都被破坏的可能性很高,但是您有时会偶然摆脱它.

Don't kid yourself that the fact that you don't see the fault on XP somehow means that the blame lies with the OS. Or that somehow you need to handle memory differently in different versions of the OS. Plenty of application programming errors are benign on some systems but manifest on others. Odds are high that your program is broken everywhere but you by chance get away with it some of the time.

这篇关于从D2006移植到XE5之后的零星访问冲突在XP兼容模式下不会发生的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆