delphi – 由于更改了8087CW模式(png stretchblt),System.Move中的内存损坏

前端之家收集整理的这篇文章主要介绍了delphi – 由于更改了8087CW模式(png stretchblt),System.Move中的内存损坏前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个奇怪的记忆腐败问题。经过好几个小时的调试和尝试,我觉得我发现了一些东西。

例如:我做一个简单的字符串分配:

sTest := 'SET LOCK_TIMEOUT ';

但是,结果有时会变成:

sTest = 'SET LOCK'#0'TIMEOUT '

所以_被替换为0字节。

当使用FPU堆栈(fild,fistp)进行快速存储器复制(在9到32个字节的情况下移动),System.Move函数中已经看到这种情况发生了一次(复制是非常棘手的,取决于时序):

...
@@SmallMove: {9..32 Byte Move}
fild    qword ptr [eax+ecx] {Load Last 8}
fild    qword ptr [eax] {Load First 8}
cmp     ecx,8
jle     @@Small16
fild    qword ptr [eax+8] {Load Second 8}
cmp     ecx,16
jle     @@Small24
fild    qword ptr [eax+16] {Load Third 8}
fistp   qword ptr [edx+16] {Save Third 8}
...

使用FPU视图和2个内存调试视图(Delphi – > View – > Debug – > cpu – > Memory)我看到它出错了…一次…无法再现…

今天早上我读了一些有关8087CW模式的信息,是的,如果这个更改成$ 27F,我得到内存损坏!通常是133F:

The difference between $133F and $027F is that $027F sets up the FPU for doing less precise calculations (limiting to Double in stead of Extended) and different infiniti handling (which was used for older FPU’s,but is not used any more).

好的,现在我发现为什么而不是什么时候!

我通过简单的检查改变了我的AsmProfiler的工作(所有功能都在进入和离开时被检查):

if Get8087CW = $27F then    //normally $1372?
  if MainThreadID = GetCurrentThreadId then  //only check mainthread
    DebugBreak;

我“分析”一些单位和dll的和宾果(见堆栈):

Windows.StretchBlt(3372289943,514,345,4211154027,13369376)
pngimage.TPNGObject.DrawPartialTrans(4211154027,(0,0),(514,345)))
pngimage.TPNGObject.Draw($7FF62450,345)))
Graphics.TCanvas.StretchDraw((0,345)),$7FECF3D0)
ExtCtrls.TImage.Paint
Controls.TGraphicControl.WMPaint((15,0))

所以发生在StretchBlt …

现在做什么?是Windows的错误还是PNG中的错误(包含在D2007中)?
还是System.Move功能不是故障安全?

注意:只是尝试重现不起作用:

Set8087CW($27F);
  ssql := 'SET LOCK_TIMEOUT ';

似乎更有异国情调…但是通过“Get8087CW = $ 27F”的debugbreak,我可以在另一个字符串中重现它:
FPU第1部分:

FPU第2部分:

FPU第3部分:

FPU决赛:腐败!

注2:也许FPU堆栈必须在System.Move中被清除?

@H_301_54@

解决方法

我没有看到这个特殊的问题,但如果FPU处于坏状态,Move肯定会被弄乱。思科的VPN驱动程序可以把事情搞砸,即使你没有做任何与网络有关的事情。

http://brianorr.blogspot.com/2006/11/intel-pentium-d-floating-point-unit.html

http://www.dankohn.com/archives/343

http://blog.excastle.com/2007/08/28/delphi-bug-of-the-day-fpu-stack-leak/(Ritchie Annand的评论)

在我们的例子中,我们检测到错误的VPN驱动程序,并使用Delphi 7版本交换Move和FillChar,用Pascal版本替换IntToStr(Int64版本使用FPU),并且,由于我们使用FastMM,因此禁用其自定义固定因为它们比System.Move更容易受到影响。

@H_301_54@ @H_301_54@

猜你在找的Delphi相关文章