// Needed for X86 systems
#ifdef _X86_
LONG SampleExceptionFilter( EXCEPTION_POINTERS *pExceptionPointer )
{
DWORD dwExCode = pExceptionPointer->ExceptionRecord->ExceptionCode;
bool fAvTrue = false;
static wchar_t wszRegisterBuffer[1024] = { 0 };
static wchar_t wszErrorBuffer[256] = { 0 };
static wchar_t wszAvBuffer[256] = { 0 };
// Switch on error code and then print it out at the end before we exit
switch(dwExCode)
{
case EXCEPTION_ACCESS_VIOLATION :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Access Violation: %08X\n", dwExCode);
StringCchPrintfW(wszAvBuffer, 256, L"\nBit Flag: %08X - Memory Address Accessed: %08X : %08X\n",
pExceptionPointer->ExceptionRecord->ExceptionInformation[0],
pExceptionPointer->ExceptionRecord->ExceptionInformation[1]
&pExceptionPointer->ExceptionRecord->ExceptionInformation[1]);
fAvTrue = true;
break;
case EXCEPTION_DATATYPE_MISALIGNMENT :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - DataType Misalignment: %08X\n", dwExCode);
break;
case EXCEPTION_BREAKPOINT :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Breakpoint: %08X\n", dwExCode);
break;
case EXCEPTION_SINGLE_STEP :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Single Step: %08X\n", dwExCode);
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Array Bounds Exceeded: %08X\n", dwExCode);
break;
case EXCEPTION_FLT_DENORMAL_OPERAND :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Float Normal Operand: %08X\n", dwExCode);
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Float Divide By Zero: %08X\n", dwExCode);
break;
case EXCEPTION_FLT_INEXACT_RESULT :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Float InExact Result: %08X\n", dwExCode);
break;
case EXCEPTION_FLT_INVALID_OPERATION :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Float Invalid Operation: %08X\n", dwExCode);
break;
case EXCEPTION_FLT_OVERFLOW :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Float Overflow: %08X\n", dwExCode);
break;
case EXCEPTION_FLT_STACK_CHECK :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Float Stack Check: %08X\n", dwExCode);
break;
case EXCEPTION_FLT_UNDERFLOW :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Float Underflow: %08X\n", dwExCode);
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Integer Divide By Zero: %08X\n", dwExCode);
break;
case EXCEPTION_INT_OVERFLOW :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Integer Overflow: %08X\n", dwExCode);
break;
case EXCEPTION_PRIV_INSTRUCTION :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Private Instruction: %08X\n", dwExCode);
break;
case EXCEPTION_IN_PAGE_ERROR :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - In Page Error: %08X\n", dwExCode);
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Illegal Instruction: %08X\n", dwExCode);
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Non-Continuable: %08X\n", dwExCode);
break;
case EXCEPTION_STACK_OVERFLOW :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Stack Overflow: %08X\n", dwExCode);
break;
case EXCEPTION_INVALID_DISPOSITION :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Invalid Disposition: %08X\n", dwExCode);
break;
case EXCEPTION_GUARD_PAGE :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Guardpage: %08X\n", dwExCode);
break;
case EXCEPTION_INVALID_HANDLE :
StringCchPrintfW(wszErrorBuffer, 256, L"\nException - Invalid Handle: %08X\n", dwExCode);
break;
case 0xE06D7363 :
StringCchPrintfW(wszErrorBuffer, 256, L"\nC++ Exception: %08X\n", dwExCode);
break;
default :
wprintf(L"\nDefault case statement. Program will continue to execute\n");
return EXCEPTION_CONTINUE_EXECUTION;
break;
}
// Print the context record data
wprintf(wszErrorBuffer);
StringCchPrintfW(wszRegisterBuffer, 1024, _T(L"EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X\n")\
_T(L"EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n")\
_T(L"CS=%04X DS=%04X SS=%04X ES=%04X FS=%04X GS=%04X"),
pExceptionPointer->ContextRecord->Eax,
pExceptionPointer->ContextRecord->Ebx,
pExceptionPointer->ContextRecord->Ecx,
pExceptionPointer->ContextRecord->Edx,
pExceptionPointer->ContextRecord->Esi,
pExceptionPointer->ContextRecord->Edi,
pExceptionPointer->ContextRecord->Ebp,
pExceptionPointer->ContextRecord->Esp,
pExceptionPointer->ContextRecord->Eip,
pExceptionPointer->ContextRecord->EFlags,
pExceptionPointer->ContextRecord->SegCs,
pExceptionPointer->ContextRecord->SegCs,
pExceptionPointer->ContextRecord->SegDs,
pExceptionPointer->ContextRecord->SegSs,
pExceptionPointer->ContextRecord->SegEs,
pExceptionPointer->ContextRecord->SegFs,
pExceptionPointer->ContextRecord->SegGs,
pExceptionPointer->ExceptionRecord->ExceptionInformation[0],
pExceptionPointer->ExceptionRecord->ExceptionInformation[1]);
// Print register buffers
wprintf(wszRegisterBuffer);
// Check to see if this was an access violation
if (fAvTrue)
{
wprintf(wszAvBuffer);
wprintf(L"\nNOTE: If the bit flag value is zero, this thread attempted to read the inaccessible data.\n");
wprintf(L"If the bit flag value is 1, this thread attempted to write to an inaccessible address.\n");
wprintf(L"The second array element specifies the virtual address of the inaccessible data.\n\n");
}
// Check the exception code and handle it
if (dwExCode == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH);
wprintf(L"\nException handler executed!\nProgram will terminate!!\n");
}
#endif
// Main entry point
int main(int argc, char *argv[])
{
HRESULT hr = S_OK;
wchar_t* wszBuffer = NULL;
wchar_t* wsString = L"This is an access violation";
__try
{
// Raise an exception in this code block
hr = StringCchCopyW(wszBuffer, BufferSize, wsString);
}
__except(SampleExceptionFilter(GetExceptionInformation())) <- Exception will be caught and handled here!!
{
// do some sort of handling if you are allowing the application to continue for debug purposes
}
wprintf(L"Out string = %ws", wszBuffer);
return 0;
}