Delphi 6 编译器选项(奔腾安全 FDIV)

问题描述 投票:0回答:3

我收到了一位用户来自 MadExcept 的崩溃报告。 异常是无效的浮点运算。

奇怪的是,调用堆栈在 @FSafeDivide 处终止。

我进行了谷歌搜索,发现这是对某些未正确执行除法的奔腾芯片的检查。 如果测试失败,所有划分都将在软件而不是硬件中完成。 我在编译器设置中打开了 Pentium-Safe FDIV 选项。

这可能导致错误吗? 我还在其他地方读到,异常类 EInvalidOp 可能是堆栈溢出或其他原因。

如果您想阅读的话,这里有一段疯狂的消息除外。

异常类:EInvalidOp 异常消息:无效的浮点运算。

thread $1014 (TMyBossThread):
00403509 M5b3.exe System                @FSafeDivide
008300c9 M5b3.exe MMyWorkerThread    317 TMyBossThread.Search
0073e87a M5b3.exe MMyManagerThread 186 TMyWorkerThread.Execute
008e8c17 M5b3.exe madExcept             HookedTThreadExecute
0042c150 M5b3.exe Classes               ThreadProc
00405354 M5b3.exe System                ThreadWrapper
008e8af9 M5b3.exe madExcept             CallThreadProcSafe
008e8b63 M5b3.exe madExcept             ThreadExceptFrame
created by main thread ($864) at:
0073e828 M5b3.exe MMyManagerThread 171 TMyManagerThread.Create
delphi floating-point division
3个回答
3
投票

首先,除非您确实有人仍在早期的 Pentium I 芯片上运行,否则您应该关闭该编译器选项。 它是为了解决一些特定 CPU 中的故障,自 1995 年以来销售的任何芯片都没有出现过该问题。

话虽如此,如果除法中存在无效的浮点运算,问题很可能出在代码中的某个地方,特别是因为 FSafeDivide 是应该产生正确结果的例程。 看一下 TMyBossThread.Search,第 317 行,看看它在那里划分了什么。 另请查看第 316 行,因为堆栈跟踪有时可以将您指向您关心的行之后的行。


1
投票

在大海捞针中搜索之前,一些评论:

  • “如果无法重现,则不是错误而是异常”。不要把时间浪费在“什么”或“为什么”上,而要花在“如何重新创建它”上。
  • 正如 Mason 所说,可能是时候删除这个编译器选项了。 (D6快10岁了)
  • 您知道它是否发生在特定的 Windows 版本上吗?例如,文本转语音在 XP 上运行良好,在 Vista 及更高版本上会出现“浮点除以零错误”。
  • 假设你的代码看起来不错,那么涉及一些浮点运算的叫什么?

最后两个是指 FPU 寄存器混乱的问题:
请参阅此处与 .Net 互操作以及有关 OpenGL 的 Set8087CW 的帮助


1
投票

这篇(德语)文章描述了一个案例,其中打开 Pentium(tm) 安全除法 ($U+) 修复了启用了 DEP 的 Windows 2003 Server 系统上的数据执行保护错误:

http://entwickler-forum.de/archive/index.php/t-41207.html

Delphi 2009 仍然具有此编译器标志,默认为 $U-(没有 Pentium(tm) 安全除法。

因此,即使我们可以忘记与硬件相关的部分(损坏的 CPU),它仍然可能会产生影响,具体取决于 DEP 等操作系统“功能”

© www.soinside.com 2019 - 2024. All rights reserved.