掩盖Delphi中的异常

前端之家收集整理的这篇文章主要介绍了掩盖Delphi中的异常前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
几天来,我一直在用异常面具努力(但徒劳无功).

我开发了一个应用程序,可以对数十万条记录进行大量浮点计算.显然,代码必须能够处理异常,尤其是与浮点计算相关的异常:溢出,ZeroDivide等.

应用程序在具有许多不同类型处理器的Windows 7(32位或64位)下正确运行,如果发生错误,则正确处理条件,引发异常并丢弃记录.

不幸的是,当我启动应用程序时,问题就出现了:在具有Intel Xeon E5-2640 v2 cpu和Windows Server 2003 R2的专用服务器上.这里不会引发异常:不会丢弃有错误的记录,因此结果会受到机器描述INF或-INF的这些数值的影响.

问题是在服务器上,错误屏蔽的默认设置与我们在Windows 7中找到的设置不同.特别是,默认情况下在服务器上调用过程GetExceptionMask我发现exZeroDivide,而如果在Windows 7上调用GetExceptionMask,则此异常是没有蒙面.结果就是我所说的:在服务器上运行应用程序时,这些异常不会引发,而是由处理器返回极值和“污染”数值来处理.

好吧,不要惊慌,我说,你只是调用(即在初始化部分)SetExceptionMask,不包括exZeroDivide,但不起作用.或者更好,虽然在调用SetExceptionMask之后,异常exZeroDivide不再被屏蔽,当执行具有浮点计算的代码时,GetExceptionMask返回的集合TArithmeticExceptionMask仍包含exZeroDivide,因此如果发生错误,则不会引发异常.

谁能告诉我调用SetExceptionMask的正确方法是什么?

屏蔽默认值可能与计算机和另一台计算机不同的原因是什么?操作系统或处理器类型?

谢谢.

解决方法

通常的原因是您正在调用清除掩码的第三方代码.它可能是您故意使用的库,但更有可能是您不是特别注意调用内容.一个常见的例子是打印机驱动程序.这些因改变浮点控制标志而臭名昭着.

下一步是确定更改控制标志的代码部分.我建议你添加调试跟踪日志记录.调用OutputDebugString就足够了,但是你可以使用更高级的日志库.在程序执行时记录控制标志的状态.在找到罪魁祸首之前,您需要几个周期来添加日志记录调用,运行,读取日志.找到更改标志的外部代码后,请确保在执行外部代码后恢复它们.

这是一个我很害怕的棘手问题.做起来并不容易.外部代码有时会使用控制标志快速松散地运行,就好像该代码是唯一存在的代码一样. Delphi RTL在处理控制标志方面也不是最好的.例如,Set8087CW不是线程安全的可能并不为人所知.

我个人经历过我自己的浮点应用程序的困难.但是你应该能够解决这些问题.祝好运!

猜你在找的Delphi相关文章