Click here to Skip to main content
15,884,731 members
Articles / Desktop Programming / Win32

SetUnhandledExceptionFilter and the C/C++ Runtime Library

Rate me:
Please Sign up or sign in to vote.
4.79/5 (26 votes)
7 Feb 2011Zlib2 min read 140.9K   3.3K   54   26
This article presents a fix for SetUnhandledExceptionFilter to work with the CRT.

Introduction

Windows provides a way for applications to override the default application "crash" handling functionality by the means of the SetUnhandledExceptionFilter function.

Usually, the SetUndhandledExceptionFilter function is used in conjunction with the crash reporting activity. Having the ability of pinpointing the line of code which caused a crash is invaluable in post mortem debugging.

Post mortem debugging has been discussed in other articles on CodeProject and is not the scope of this article.

Here is how a simple unhandled exception filter (which displays only "Gotcha!" in the console) looks like:

C++
bool g_showCrashDialog = false;

LONG WINAPI OurCrashHandler(EXCEPTION_POINTERS * /*ExceptionInfo*/)
{
    std::cout << "Gotcha!" << std::endl;

    return g_showCrashDialog ? EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER;
}

If the crash handling function returns EXCEPTION_EXECUTE_HANDLER, the Operating System will display the default crash dialog or call the Just in time (JIT) debugger if such a debugger is installed on the system.

In order to test the code, we will simulate a null pointer invalid access like this:

C++
int main()
{
    ::SetUnhandledExceptionFilter(OurCrashHandler);

    std::cout << "Normal null pointer crash" << std::endl;

    char *p = 0;
    *p = 5;
}

The program should then display:

Normal null pointer crash
Gotcha!

The C/C++ Runtime Library

The C/C++ Runtime Library will remove any custom crash handler in certain circumstances, and our crash handler will never be called.

Circumstances such as:

abort() function

C++
void AbortCrash()
{
    std::cout << "Calling Abort" << std::endl;
    abort();
}

will display:

Calling Abort

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

abort is called internally in the CRT, we need to catch all those cases too.

Out of bounds vector access

C++
void OutOfBoundsVectorCrash()
{
    std::cout << "std::vector out of bounds crash!" << std::endl;

    std::vector<int> v;
    v[0] = 5;
}

Will display:

std::vector out of bounds crash!

Pure virtual function call

C++
void VirtualFunctionCallCrash()
{
    struct B
    {
        B()
        {
            std::cout << "Pure Virtual Function Call crash!" << std::endl;
            Bar();
        }

        virtual void Foo() = 0;

        void Bar()
        {
            Foo();
        }
    };

    struct D: public B
    {
        void Foo()
        {
        }
    };

    B* b = new D;
    // Just to silence the warning C4101:
    //    'VirtualFunctionCallCrash::B::Foo' : unreferenced local variable
    b->Foo(); 
}

Will display:

Pure Virtual Function Call crash!
R6025
- pure virtual function call

The fix

In order to have the above cases also caught, we need to redirect the SetUnhandledExceptionFilter function to a dummy function so that when the CRT calls SetUnhandledExceptionFilter(0) in order to remove any custom crash handlers, it will call our dummy function.

The redirection was done using the CAPIHook class presented in Chapter 22: DLL Injection and API Hooking of the book Windows via C/C++, Fifth Edition written by Jeffrey Richter and Christophe Nasarre, Microsoft Press (c) 2008.

The code looks like:

C++
LONG WINAPI RedirectedSetUnhandledExceptionFilter(EXCEPTION_POINTERS * /*ExceptionInfo*/)
{
    // When the CRT calls SetUnhandledExceptionFilter with NULL parameter
    // our handler will not get removed.
    return 0;
}

int main()
{
    ::SetUnhandledExceptionFilter(OurCrashHandler);

    CAPIHook apiHook("kernel32.dll", 
      "SetUnhandledExceptionFilter", 
      (PROC)RedirectedSetUnhandledExceptionFilter);

    // Code that crashes
}

64 bit programs

The redirection procedure works for 32 bit code as well as for 64 bit code. The sample code provides 32 bit and 64 bit compiler targets.

Static vs. dynamic CRT linking

The code works only with dynamic CRT linking (default behavior).

History

  • 07.02.2011: Initial release.

License

This article, along with any associated source code and files, is licensed under The zlib/libpng License


Written By
Software Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionDoesn't seem to work with modern VC compilers Pin
Member 1486726713-Aug-20 19:07
Member 1486726713-Aug-20 19:07 
QuestionOurCrashHandler function return EXCEPTION_CONTINUE_SEARCH, the Operating System will display the default crash dialog Pin
zhenguoli6-Sep-19 19:16
zhenguoli6-Sep-19 19:16 
Suggestionunhandled Excption filter is not working in call back funtions Flash Showwave Active X object. Pin
SrinivasLadi23-Dec-13 3:22
SrinivasLadi23-Dec-13 3:22 
QuestionI need help Pin
Member 1020314019-Aug-13 16:45
Member 1020314019-Aug-13 16:45 
GeneralMy vote of 5 Pin
JunfengGuo18-Sep-12 17:19
JunfengGuo18-Sep-12 17:19 
GeneralMy vote of 5 Pin
Ajay Vijayvargiya13-Jun-12 6:35
Ajay Vijayvargiya13-Jun-12 6:35 
QuestionStatic linking? Pin
tiresias24-Feb-12 2:20
tiresias24-Feb-12 2:20 
GeneralMy vote of 5 Pin
j5sung27-Jun-11 23:10
j5sung27-Jun-11 23:10 
QuestionOther errors? Pin
martin_bisson22-Feb-11 15:39
martin_bisson22-Feb-11 15:39 
AnswerRe: Other errors? Pin
Cristian Adam23-Feb-11 2:27
Cristian Adam23-Feb-11 2:27 
GeneralRe: Other errors? Pin
martin_bisson23-Feb-11 3:29
martin_bisson23-Feb-11 3:29 
GeneralRe: Other errors? Pin
Cristian Adam24-Feb-11 0:00
Cristian Adam24-Feb-11 0:00 
GeneralRe: Other errors? Pin
martin_bisson24-Feb-11 6:36
martin_bisson24-Feb-11 6:36 
GeneralRe: Other errors? Pin
Ajay Vijayvargiya14-Mar-11 19:54
Ajay Vijayvargiya14-Mar-11 19:54 
GeneralRe: Other errors? Pin
Alexander Miloslavsky5-Jul-12 3:37
Alexander Miloslavsky5-Jul-12 3:37 
GeneralRe: Other errors? Pin
cmellano4-Dec-12 9:41
cmellano4-Dec-12 9:41 
GeneralRe: Other errors? Pin
Alexander Miloslavsky4-Dec-12 9:50
Alexander Miloslavsky4-Dec-12 9:50 
GeneralMy vote of 5 Pin
ytfrdfiw20-Feb-11 16:31
ytfrdfiw20-Feb-11 16:31 
GeneralMy vote of 5, but with a little addition. Pin
Vadim Nazarenko14-Feb-11 8:24
Vadim Nazarenko14-Feb-11 8:24 
GeneralRe: My vote of 5, but with a little addition. Pin
Cristian Adam14-Feb-11 10:16
Cristian Adam14-Feb-11 10:16 
GeneralAddVectoredExceptionHandler Pin
Naveen14-Feb-11 1:23
Naveen14-Feb-11 1:23 
GeneralRe: AddVectoredExceptionHandler Pin
Cristian Adam14-Feb-11 2:15
Cristian Adam14-Feb-11 2:15 
GeneralRe: AddVectoredExceptionHandler Pin
Naveen14-Feb-11 19:02
Naveen14-Feb-11 19:02 
Hmm..The problem is that in the case of Pure virtual function call and abort() call, there is no exception generated, CRT directly calls the UnhandledExceptionFilter() function. Thats why the vectored execption handler is not getting involked..

GeneralNice article Pin
Snorri Kristjansson7-Feb-11 22:32
professionalSnorri Kristjansson7-Feb-11 22:32 
GeneralRe: Nice article Pin
Cristian Adam8-Feb-11 22:27
Cristian Adam8-Feb-11 22:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.