Floating point exceptions with UnhandledExceptionFilter

Started by Druesukker, June 30, 2011, 09:34:32 AM

Previous topic - Next topic

Druesukker

Hello everyone  :bg

I am learning to catch exceptions with Structured exception handling (SEH). Therefore i am trying to buind a routine which can work as my "default" UnhandledExceptionFilter.
It doesn't let me INVOKE a MessageBoxA when i get a floating point exception. I can print the exception code to the console with WriteConsole though.
It works very well when I'm not enabling the Floating point exceptions with the control word.

I have tried to dissasm some C code because i wanted to find out about the routines _clearfp() and _controlfp(arg, arg), but it didn't help me at all.
I really hope someone can help me  :bg

Here is my code:

TITLE This file handles the UnhandledExceptionFilter

.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE

INCLUDE windows.inc
INCLUDE kernel32.inc
INCLUDE user32.inc

INCLUDELIB masm32.lib
szCatStr PROTO lpszSource:DWORD, lpszAdd:DWORD

.CONST
msgTitle DB "Final exception filter.",0

szACCESS_VIOLATION DB "EXCEPTION_ACCESS_VIOLATION",0
szARRAY_BOUNDS_EXCEEDED DB "EXCEPTION_ARRAY_BOUNDS_EXCEEDED",0
szBREAKPOINT DB "EXCEPTION_BREAKPOINT",0
szDATATYPE_MISALIGNMENT DB "EXCEPTION_DATATYPE_MISALIGNMENT",0
szFLT_DENORMAL_OPERAND DB "EXCEPTION_FLT_DENORMAL_OPERAND",0
szFLT_DIVIDE_BY_ZERO  DB "EXCEPTION_FLT_DIVIDE_BY_ZERO",0
szFLT_INEXACT_RESULT  DB "EXCEPTION_FLT_INEXACT_RESULT",0
szFLT_INVALID_OPERATION DB "EXCEPTION_FLT_INVALID_OPERATION",0
szFLT_OVERFLOW  DB "EXCEPTION_FLT_OVERFLOW",0
szFLT_STACK_CHECK  DB "EXCEPTION_FLT_STACK_CHECK",0
szFLT_UNDERFLOW DB "EXCEPTION_FLT_UNDERFLOW",0
szILLEGAL_INSTRUCTION  DB "EXCEPTION_ILLEGAL_INSTRUCTION",0
szIN_PAGE_ERROR DB "EXCEPTION_IN_PAGE_ERROR",0
szINT_DIVIDE_BY_ZERO  DB "EXCEPTION_INT_DIVIDE_BY_ZERO",0
szINT_OVERFLOW  DB "EXCEPTION_INT_OVERFLOW",0
szPRIV_INSTRUCTION  DB "EXCEPTION_PRIV_INSTRUCTION",0
szSINGLE_STEP  DB "EXCEPTION_SINGLE_STEP",0
szUNKNOWN_EXCEPTION DB "EXCEPTION_UNKNOWN_EXCEPTION",0

.DATA
returnString DB "Unhandled exception occured.", \
"Exception code is: ",13,10, \
35 dup(0)
dummyVaraible DD ?

.CODE
FinalExHandler PROC C, pExPointers:PTR EXCEPTION_POINTERS

mov eax, pExPointers
mov edx, (EXCEPTION_POINTERS PTR [eax]).pExceptionRecord
mov edx, (EXCEPTION_RECORD PTR [edx]).ExceptionCode

.IF edx == EXCEPTION_ACCESS_VIOLATION
mov eax, OFFSET szACCESS_VIOLATION
.ELSEIF edx == EXCEPTION_ARRAY_BOUNDS_EXCEEDED
mov eax, OFFSET szARRAY_BOUNDS_EXCEEDED
.ELSEIF edx == EXCEPTION_BREAKPOINT
mov eax, OFFSET szBREAKPOINT
.ELSEIF edx == EXCEPTION_DATATYPE_MISALIGNMENT
mov eax, OFFSET szDATATYPE_MISALIGNMENT
.ELSEIF edx == EXCEPTION_FLT_DENORMAL_OPERAND
mov eax, OFFSET szFLT_DENORMAL_OPERAND
.ELSEIF edx == EXCEPTION_FLT_DIVIDE_BY_ZERO
mov eax, OFFSET szFLT_DIVIDE_BY_ZERO
.ELSEIF edx == EXCEPTION_FLT_INEXACT_RESULT
mov eax, OFFSET szFLT_INEXACT_RESULT
.ELSEIF edx == EXCEPTION_FLT_INVALID_OPERATION
mov eax, OFFSET szFLT_INVALID_OPERATION
.ELSEIF edx == EXCEPTION_FLT_OVERFLOW
mov eax, OFFSET szFLT_OVERFLOW
.ELSEIF edx == EXCEPTION_FLT_STACK_CHECK
mov eax, OFFSET szFLT_STACK_CHECK
.ELSEIF edx == EXCEPTION_FLT_UNDERFLOW
mov eax, OFFSET szFLT_UNDERFLOW
.ELSEIF edx == EXCEPTION_ILLEGAL_INSTRUCTION
mov eax, OFFSET szILLEGAL_INSTRUCTION
.ELSEIF edx == EXCEPTION_IN_PAGE_ERROR
mov eax, OFFSET szIN_PAGE_ERROR
.ELSEIF edx == EXCEPTION_INT_DIVIDE_BY_ZERO
mov eax, OFFSET szINT_DIVIDE_BY_ZERO
.ELSEIF edx == EXCEPTION_INT_OVERFLOW
mov eax, OFFSET szINT_OVERFLOW
.ELSEIF edx == EXCEPTION_PRIV_INSTRUCTION
mov eax, OFFSET szPRIV_INSTRUCTION
.ELSEIF edx == EXCEPTION_SINGLE_STEP
mov eax, OFFSET szSINGLE_STEP
.ELSE
mov eax, OFFSET szUNKNOWN_EXCEPTION
.ENDIF

; Get string with exception code in the end
INVOKE szCatStr, ADDR returnString, eax

; Write the code to the console WORKS
INVOKE GetStdHandle, STD_OUTPUT_HANDLE
INVOKE WriteConsole, eax, ADDR returnString, LENGTHOF returnString, ADDR dummyVaraible, NULL

; Im not able to call MessageBoxA when i get floating point exception
INVOKE MessageBoxA, NULL, ADDR returnString, ADDR msgTitle, MB_OK OR MB_ICONERROR

mov eax, EXCEPTION_NONCONTINUABLE
ret
FinalExHandler ENDP

END


TITLE This file creates a floating point exception and Sets the UnhandledExceptionFilter

.386
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE

INCLUDE windows.inc
INCLUDE kernel32.inc

FinalExHandler PROTO NEAR C, pExPointers:PTR EXCEPTION_POINTERS

.DATA?
result REAL8 ? ; Result of div by zero
controlWord DW ? ; Floating coltrol word register

.CODE
Main PROC

INVOKE SetUnhandledExceptionFilter, FinalExHandler

finit
fstcw controlWord
and controlWord, 0FFFFFFAh
fldcw controlWord

; create exception
; EXCEPTION_FLT_INVALID_OPERATION
fldz
fld st(0)
fdiv
fstp result

INVOKE ExitProcess, 0
Main ENDP
END Main

Druesukker

I solved the problem myself.
I had to clear the floating point exception flags before invoking the MessageBox with: fnclex

raymond

Quote; Get string with exception code in the end
       INVOKE    szCatStr, ADDR returnString, eax

If you intend to use your exception handler only once before exiting your program, the above is OK. Otherwise, you should reinsert the terminating "0" where you intend to concatenate your exception code in the output message before calling szCatStr.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

Druesukker

Yea it is accually not a "handler" since it just pops a message box telling which exception occurred, and then terminates the program after doing unwinding...