【发布时间】:2012-11-08 21:45:12
【问题描述】:
这几天一直困扰着我!
我们有一个应用程序正在运行被零除。该应用程序是专门为在这种情况下引发异常而构建的,通过调用 _controlfp_s 函数来更改浮点异常的掩码。
现在,当我们在几乎所有机器上运行被零除时,Visual Studio 2005 调试器会在源文件中的适当位置中断。但是,在 1 台机器上,中断位置遍布各处,似乎与中断的实际原因无关。所以作为测试,我只用以下几行代码构建了一个简单的 C win32 程序:
int main(int argc, char *argv[])
{
float temp1, temp2, temp3;
unsigned int control;
_controlfp_s(&control, (_EM_UNDERFLOW + _EM_INEXACT, _MCW_EM);
temp1=1.0;
temp2=0.0;
temp3=temp1/temp2;
return 0;
}
在所有那些“好”的机器上,代码确实在 temp3 处中断。但是,在坏机器上,代码在以下位置中断:
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\crt\src\tidtable.c
功能:
__set_flsgetvalue()
在我逐步执行汇编代码时查看寄存器,一切看起来都很好,直到我点击“fstp”指令......然后所有寄存器似乎都搞砸了(与在一台好的机器上看起来一样)。在比较好与坏的堆栈时,我还看到坏机器上的堆栈条目,而我在好机器上看不到......
我在这里跳过了很多细节,以尽量缩短第一次通过的时间……但如果有人愿意提供帮助,我会补充更多。
注意事项: 操作系统 Win7 x64,运行所有最新的 VS2005 服务包。与运行相同软件和服务包的类似(工作)机器相比。在 VS2010 上运行时出现同样奇怪的行为。
提前致谢。
【问题讨论】:
-
其中许多情况并未立即检测到,而是在某些操作发现其处于不良状态之后很久才检测到。这种行为很可能是特定于 CPU 的。
-
另外请注意,我绝望地卸载/重新安装了与 Visual Studio 相关的所有内容。当然,结果相同。
-
问题是......在我测试过的每台机器(win 7 x64,win server 2008 R2,XP)上,这个中断工作得非常好......而且它总是像预期的。这段代码很老,而且一直有效。我认为这可能是计算机 BIOS 中的某些东西或某些东西……某些 MB/CPU 机器特定的优化搞砸了处理……但是当我关闭除 1 个 cpu 和所有优化集以外的所有东西时,我仍然得到相同的结果通过 BIOS。
-
另外,如果应用程序没有专门调用 _controlfp_s,我相信您所说的是正确的...此时,某些代码可能会对某些错误的浮点值做出意外反应...但是当专门调用 _controlfp_s 时,我相信这会强制在检测到异常时抛出异常......正如在所有好的机器上单步执行汇编代码时所看到的那样。
-
好吧,Doug(因为你是唯一一个尝试过的人)...我以为你会对我的额外测试结果感兴趣。我已采取以下故障排除步骤:
标签: c winapi floating-point visual-studio-debugging unhandled-exception