第三方代码正在修改FPU控制字 [英] Third party code is modifying the FPU control word

查看:287
本文介绍了第三方代码正在修改FPU控制字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(问题是结束)

我我的开发环境是Windows和Visual C ++ 2008.正常的FPU控制字指定了一个第三方的COM组件,不断改变FPU控制字。

I am getting severe head aches over a third party COM component that keeps changing the FPU control word.

在各种条件下都不应该抛出异常。我已经验证了,同时查看 float.h 中找到的 _CW_DEFAULT 宏,以及查看控件在启动时调试器中的字。

My development environment is Windows and Visual C++ 2008. The normal FPU control word specifies that no exceptions should be thrown during various conditions. I have verified this with both looking at the _CW_DEFAULT macro found in float.h, as well as looking at the control word in the debugger at startup.

每当我打电话到COM对象时,控制字在返回时被修改。这很容易防御。我只是重新设置控制字,一切都很好。问题是当COM组件开始调用我的事件接收器。我可以在收到活动通知后立即重新控制字词来保护我的代码,但是一旦从事件呼叫返回,我就不能做任何事情。

Everytime I make a call into the COM object, the control word is modified upon return. This is easy to defend against. I simply reset the control word, and all is good. The problem is when the COM component starts calling my event sink. I can protect my code by reseting the control word as soon as I receive the event call, but I can't do anything as soon as I return from the event call.

我没有这个COM组件的源代码,但我与作者联系。我从他那里得到的答复是嗯?我不认为他有丝毫的线索,我在说什么,所以我怕我必须自己做一些事情。我相信他的运行时(我认为这是Delphi或Borland C ++,因为DLL充满了符号名称,全部以资本T开头)或其他第三方代码,这是导致问题的。我不认为他的代码显然修改了FPU控制字。

I don't have the source for this COM component, but I am in contact with the author. The responses I have had from him has been "Huh?". I don't think he has the slightest clue what I'm talking about, so I fear I have to do something about this myself. I believe that his runtime (I think it's either Delphi or Borland C++, because the DLL is full of symbol names, all starting with capital T) , or some other third party code he's using, that's causing the problem. I don't think his code explicitly modifies the FPU control word.

那么,我该怎么办?从商业角度来看,使用这个第三方组件是至关重要的。从技术的角度来看,我可以把它淹没,并且自己实现通信的协议。然而,这将是非常昂贵的,因为该协议涉及处理信用卡交易。我们不想承担责任。

So, what can I do? From a business point of view, it is imperative to use this third party component. From a technical point of view, I could ditch it, and implement the communication's protocol myself. However, that would be really expensive, as this protocol involves handling credit card transactions. We don't want to take on the liability.

我迫切需要一个黑客,或有关Borland产品中FPU设置的一些有用信息,我可以传递给

I desperately need a hack-around, or some useful information about FPU settings in Borland products that I can pass along to the author of the component.

是否有任何可以做?我不认为组件作者有什么需要解决它(通过从他相当无知的答复来判断)。

Is there anything I can do? I don't think the component author has what it takes to fix it (by judging from his rather clueless responses).

我一直在想着安装我的自己的异常处理程序,其中我只是重新设置处理程序中的控制字,并告诉Windows继续执行。我尝试使用 SetUnhandledExceptionFilter()安装处理程序,但由于某些原因,异常未被捕获。

I have been toying with the idea of installing my own exception handler, in which I just reset the control word in the handler, and tell Windows to continue executing. I tried installing the handler with SetUnhandledExceptionFilter(), but for some reason, the exceptions are not caught.


  1. 为什么我没有捕获例外?

  2. 如果我成功抓住FPU异常,重新设置FPU控制字,只是让执行继续,因为没有发生 - 是否全部下注?



更新



我想感谢大家的建议。我已经发送了作者的指示,说明他可以做些什么,使生活不仅仅是我,而且他的代码的许多其他客户。我向他建议,他应该在 DllMain(DLL_PROCESS_ATTACH)下采样FPU控制字,并保存控制字以供以后使用,以便在调用我的事件之前可以重置FPU CW处理程序,并从我的电话返回。

Update

I would like to thank everyone for their suggestions. I have sent the author instructions on what he can do to make life easier for not just me, but many other clients of his code. I suggested to him that he should sample the FPU control word at DllMain(DLL_PROCESS_ATTACH), and save the control word for later, so that he can reset FPU CW before calling my event handlers, and returning from my calls.

现在,如果有任何人感兴趣,我有一个黑客。黑客攻击可能是一个坏的,因为我不知道他的代码将会做什么。我早些时候已经收到确认,他没有在他的代码中使用任何浮点数,所以这应该是安全的,除了他使用的一些第三方代码,它依赖于FPU异常。

For now, I have a hack-around if anyone is interested. The hack-around is potentially a bad one, because I don't know what it'll do to his code. I have received confirmation earlier that he does not use any floating point numbers in his code, so this should be safe, barring some third party code he uses, that relies on FPU exceptions.

我对我的应用程序进行了两项修改:

The two modifications I have made to my app:



  1. 安装一个窗口挂钩( WH_CALLWNDPROC )来捕捉消息泵被绕过的角落情况

  1. Wrap my message pump
  2. Install a window hook (WH_CALLWNDPROC) to catch the corner cases where the message pump is bypassed

在这两种情况下,我检查FPU CW是否已更改。如果有,我将其重置为 _CW_DEFAULT

In both instances, I check if the FPU CW has changed. If it has, I reset it to _CW_DEFAULT.

推荐答案

您的诊断认为该组件是用Embarcadero产品编写的,很可能是真实的。 Delphi的运行库确实启用了浮点异常,对于C ++ Builder来说也是一样。

I think your diagnosis that the component is written in an Embarcadero product is very likely to be true. Delphi's runtime library does indeed enable floating point exceptions, same for C++ Builder.

关于Embarcaderos工具的一个好处是浮点错误被转换成语言异常数字编码很容易。这对你来说是不太安慰的!

One of the nice things about Embarcaderos tools is that floating point errors get converted into language exceptions which makes numerical coding a lot easier. That is going to be of little consolation to you!

这个整个区域是一个巨大的PITA。没有关于FP控制词的规则。这是一个完全免费的。

This entire area is a colossal PITA. There are no rules whatsoever regarding the FP controls word. It's a total free-for-all.

我不认为捕获未处理的异常不会完成工作,因为MS C ++运行时可能已经是抓住这些例外,但我不是这方面的专家,可能是错误的。

I don't believe that catching unhandled exceptions isn't going to get the job done because the MS C++ runtime will presumably already be catching these exceptions, but I'm no expert in that area and I may be wrong.

我相信你唯一现实的解决方案是将FPU设置为你希望它在执行到达您的代码时,并在执行离开您的代码时将其还原。我不太了解COM事件接收器,以了解为什么他们提出了这样做的障碍。

I believe that your only realistic solution is to set the FPU to what you want it to be whenever execution arrives in your code, and restore it when execution leaves your code. I don't know enough about COM event sinks to understand why they present an obstacle to doing this.

我的产品包括在Delphi中实现的DLL,问题。大多数呼叫的客户端都有一个禁用异常的FPU控制字。我们采用的策略是记住8087CW的入门级,在执行代码之前将其设置为标准的Delphi CW,然后在退出点恢复。在进行回调之前,还要保留呼叫者的8087CW,我们也要小心处理回调。这是一个简单的DLL而不是一个COM对象,因此可能会更简单一些。

My product includes a DLL implemented in Delphi and I suffer from the reverse problem. Mostly the clients that call in have an FPU control word that disables exceptions. The strategy we adopt is to remember the 8087CW on entry, set it to the standard Delphi CW before executing code, and then restore it at the exit point. We take care to deal with callbacks too by restoring the caller's 8087CW before making the callback. This is a plain DLL rather than a COM object so it's probably a bit simpler.

如果您决定尝试让COM供应商修改代码,那么需要致电 Set8087CW() 功能

If you decide to attempt to get the COM supplier to modify their code then they need to call the Set8087CW() function.

但是,由于游戏没有规则,我相信COM对象供应商将拒绝更改代码并放置on回到你身边。

However, since there are no rules to the game, I believe that the COM object vendor would be justified in refusing to change their code and to put the onus back on you.

对不起,如果这不是一个100%的决定性答案,但我无法将所有这些想法纳入评论!

Sorry if this is not a 100% conclusive answer, but I couldn't get all these thoughts into a comment!

这篇关于第三方代码正在修改FPU控制字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆