Third party code is modifying the FPU control word

后端 未结 2 988
孤独总比滥情好
孤独总比滥情好 2021-02-14 13:49

The introduction - the long and boring part

(The question is at the end)

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

相关标签:
2条回答
  • 2021-02-14 13:55

    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.

    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!

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

    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.

    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.

    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.

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

    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.

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

    0 讨论(0)
  • 2021-02-14 14:05

    Although FP control word is per-thread, dllmain functions are called when new threads are created, i don't think you can avoid this short of going to a new process.

    I suggest you spin-off a new process to run the COM and chat with the process with your favorite inter-process communication method (e.g. windows message, out-of-proc COM, named pipe, socket, etc). In this way the COM server is free to do all kinds of damage (including crashing itself) without bring your host process down.

    Another idea is to write a DLL whose sole purpose is to reset the FPU in its DllMain and load it immediately after the offending DLL. Windows is probably using the loading order to call DllMain when new threads are created, including threads created by the COM server. Note this depends on Windows's internal behavior. Also the COM server may actually depends on fp exceptions since it enables them. Disabling FP exceptions may causes the COM server to behave unexpectedly.

    0 讨论(0)
提交回复
热议问题