gpt4 book ai didi

delphi - 由于更改 8087CW 模式而导致 System.Move 内存损坏 (png +stretchblt)

转载 作者:行者123 更新时间:2023-12-03 14:34:05 25 4
gpt4 key购买 nike

我有一个奇怪的内存损坏问题。经过几个小时的调试和尝试,我想我找到了一些东西。

例如:我做了一个简单的字符串赋值:

sTest := 'SET LOCK_TIMEOUT ';

但是,结果有时会变成:

sTest = 'SET LOCK'#0'TIMEOUT '

因此,_ 被 0 字节替换。

我在 System.Move 函数中看到过这种情况发生一次(复制很棘手,取决于时间),当时它使用 FPU 堆栈(fild、fistp)进行快速内存复制(在要移动 9 到 32 字节的情况下) ):

...
@@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 View 和 2 个内存调试 View (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,0,0,514,345,4211154027,0,0,514,345,13369376)
pngimage.TPNGObject.DrawPartialTrans(4211154027,(0, 0, 514, 345, (0, 0), (514, 345)))
pngimage.TPNGObject.Draw($7FF62450,(0, 0, 514, 345, (0, 0), (514, 345)))
Graphics.TCanvas.StretchDraw((0, 0, 514, 345, (0, 0), (514, 345)),$7FECF3D0)
ExtCtrls.TImage.Paint
Controls.TGraphicControl.WMPaint((15, 4211154027, 0, 0))

所以它发生在 StretchBlt 中......

现在该怎么办?是 Windows 的故障,还是 PNG 的错误(包含在 D2007 中)?或者 System.Move 函数不是故障安全的?

注意:仅仅尝试重现是行不通的:

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

它似乎更奇特......但是通过“Get8087CW = $27F”上的 debugbreak 我可以在其他字符串上重现它:FPU 第 1 部分: FPU part 1FPU 第 2 部分: FPU part 2FPU 第 3 部分: FPU part 3FPU 最终:损坏!: FPU Final: corrupt!

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

最佳答案

我还没有看到这个特殊问题,但是如果 FPU 处于不良状态,Move 肯定会变得困惑。即使您没有做任何与网络相关的事情,Cisco 的 VPN 驱动程序也会把事情搞砸。

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

https://web.archive.org/web/20160601043520/http://www.dankohn.com/archives/343

http://blog.excastle.com/2007/08/28/delphi-bug-of-the-day-fpu-stack-leak/ (里奇·安南评论)

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

关于delphi - 由于更改 8087CW 模式而导致 System.Move 内存损坏 (png +stretchblt),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2584654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com