Question

I am using the following MSVC++ console application code (running on Windows 8.1, Release, Win32) to try and return a top-level exception back to me:

#include "stdafx.h"
#include <Windows.h>
#include <iostream>

using namespace std; 

LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS exception)
{
    printf("Got an unhandled exception.");
    return EXCEPTION_CONTINUE_SEARCH;
}

int _tmain(int argc, _TCHAR* argv[])
{
    SetUnhandledExceptionFilter(UnhandledExceptionFilter);
    int a = 0;
    int b = 0;
    int c = a / b;
    cin.get();
    return 0;
}

My UnhandledExceptionFilter doesn't actually seem to ever get called on the divide by zero exception that is being thrown in this example, otherwise I would expect the "Got an unhandled exception" log message to show up. Why is that?

Was it helpful?

Solution

Integer division by zero is undefined behavior. If an implementation choose to raise an exception for that (or for any other undefined behavior), that's fine. If an implementation chooses not to raise an exception for some undefined behavior, that's also fine. Whatever the implementation does when confronted with undefined behavior is fine. It's not their problem.

Apparently MSVC++ running on Windows 8.1, Win32 doesn't raise an exception on division by zero.

You should never expect undefined behavior to result in something expected.

OTHER TIPS

The function specified by SetUnhandledExceptionFilter() won't be called if the application is running under a debugger, the idea being that SetUnhandledExceptionFilter() should only be used to generate a crash dump and then exit an application. This isn't very useful if you have a debugger attached, so the debugger will handle the exception first.

The MSDN documentation references this:

After calling this function, if an exception occurs in a process that is not being debugged, and the exception makes it to the unhandled exception filter, that filter will call the exception filter function specified by the lpTopLevelExceptionFilter parameter.

  1. as @zhenguoli says, UnhandledExceptionFilter is defined in kernel32.lib so it will not link. You need to name your exception filter something else. UnhandledExceptionFilter is what calls your exception Handler set by SetUnhandledExceptionFilter.

  2. @DavidHammen is unclear because div by zero is indeed handled with exception vector 0 on x86 and GetExceptionCode() would return EXCEPTION_INT_DIVIDE_BY_ZERO. But, as @davidbak says, in the OP's example compiler does not allow this as the variable c isn't used and will be optimised out. If c were used, then the exception handler at vector 0 would start unwinding the stack and eventually call UnhandledExceptionFilter as a filter expression which is wrapped around the thread entry function in RtlUserThreadStart, which will then call your handler (the thread is started with RtlUserThreadStart as the entry function with the real thread entry function as a parameter). The .exe entry function will initialise the CRT and then call main. You are right to use SEH because divbyzero can't be caught by C++ exception handling, which only responds to throw.

Divide By Zero is actually a CPU trap, more than an exception as in programming sense. You should define a trap handler instead of an exception handler.

It looks to me like the exceptions isn't actually a true unhandled exception from the OS perspective. You're calling printf, so you have linked in the CRT. IIRC, the CRT handles exceptions escaping from main, but from the OS viewpoint an unhandled exception is one that escapes the true entry point - i.e. the CRT function which calls main.

I believe you actually want a Vectored Exception Handler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top