I am attempting to write an unhandled exception filter ( see SetUnhandledExceptionFilter()) to use with Windows SEH to report invalid floating point operations. I'd like to trap the exception, print a stack trace, then disable floating point exceptions and resume execution with the resulting non-finite or not-a-number value.
I wrote the simple program below to demonstrate the ability to catch the exception and resume execution. Note the use of #ifdef _WIN64, as the definition of the ContextRecord changes depending on the targeted architecture (WIN32 uses "FloatSave", WIN64 uses "FltSave").
#include "stdafx.h"
#include <float.h>
#include <Windows.h>
double zero = 0.0;
LONG WINAPI myfunc(EXCEPTION_POINTERS * ExceptionInfo){
/* clear the exception */
unsigned int stat = _clear87();
/* disable fp exceptions*/
unsigned int ctrl1 = _control87(_MCW_EM, _MCW_EM);
/* Disable and clear fp exceptions in the exception context */
#if _WIN64
ExceptionInfo->ContextRecord->FltSave.ControlWord = ctrl1;
ExceptionInfo->ContextRecord->FltSave.StatusWord = 0;
#else
ExceptionInfo->ContextRecord->FloatSave.ControlWord = ctrl1;
ExceptionInfo->ContextRecord->FloatSave.StatusWord = 0;
#endif
printf("#########Caught Ya#####!\n");
return EXCEPTION_CONTINUE_EXECUTION;
}
int _tmain(int argc, _TCHAR* argv[])
{
double a;
/* enable fp exceptions*/
_controlfp(0, _MCW_EM);
/* Setup our unhandled exception filter */
SetUnhandledExceptionFilter(myfunc);
/* do something bad */
a = 5.0 / zero;
printf("a = %f\n",a);
return 0;
}
When run as a WIN32 .exe, the above program runs as expected, with the output:
#########Caught Ya#####!
a = -1.#IND00
However, when run as a WIN64 .exe, the program enters an infinite loop, continuously re-catching the floating point exception:
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
...
This seems to indicate that I'm not successful at configuring the floating point unit, which I imagine is related to the different definition of ContextRecord between WIN32 and WIN64, but I haven't been able to find any good related documentation on exactly how to set the floating point context.
Any thoughts on how to correctly set the floating point context for WIN64?
Thanks in advance