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 FPU control word.
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.
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.
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.
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.
The questions
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).
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.
- Why aren't I catching the exceptions?
- If I succeed with catching FPU exceptions, resetting the FPU control word, and just let the execution continue as nothing has happened - are all bets off then?
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.
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:
- Wrap my message pump
- Install a window hook (
WH_CALLWNDPROC
) to catch the corner cases where the message pump is bypassed
In both instances, I check if the FPU CW has changed. If it has, I reset it to _CW_DEFAULT
.