locked
Catching exceptions thrown without try/catch RRS feed

  • Question

  • I recall reading about how exceptions could be caught without the use of try/catch. Basically when an exception is thrown such as "Unhandled exception" via derefencing a null pointer, there would be a process that is triggered even when a try/catch is not coded for the exception. I believe it had something to do with a top level library that you write then include in your code. Unfortunately documentation on such a method seems to be non-existent but I have seen/heard of such a method being done before. Could someone please explain how this is done? From poking around I see there is "SetUnhandledExceptionFilter". However, from what I have seen/tested this only works in release mode and not in debug. Is there a way to get this to work in Debug?
    Friday, June 3, 2011 4:34 AM

Answers

  • From what I gather you can't. The way exceptions work is

    A first chance exception notification gets delivered to the debugger if one is attached. (A debugger can handle this exception if it wants to.)

    It walks up the exception chain checking to see if one will handle it.

    If it is not handled a second chance exception notification is sent to the debugger, giving it another chance to handle it (this is where VS handles the exception).

    The system calls the unhandle exception handler.

    The reason why you don't get the unhandled exception handler being called when VS is because it takes the opportunity as the attached debugger to handle the exception at the second chance exception stage. By this stage the only thing left is the unhandled exception handler, and the information that VS gets out is more useful for developers than what the default handler does. There is also no way to switch off the exception handling feature either.

    If you don't mind losing all of the debugging capabilities you can start without debugging (ctrl + f5) in VS. But you will lose the source stepping capabilities too. However, when VS is attached as the debugger then the unhandled exception handler will never be called because VS will always handle the exception.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.
    Visit my (not very good) blog at
    http://ccprogramming.wordpress.com/
    • Marked as answer by judeclarke Sunday, July 3, 2011 7:10 PM
    Saturday, June 25, 2011 8:36 PM

All replies

  • SetUnhandledExceptionFilter should be working in debug version as well...now what happens in  debug version? May be the debug version of CRT library installs another filter function on top of it. Also in some places of CRT i have seen it directly calling UnhandledExceptionFilter function( eg: inside abort() function )

    Also you can try AddVectoredExceptionHandler function..


    Nave [My Blog]
    Friday, June 3, 2011 8:03 AM
  • You are probably looking for __try/__catch/__finally.  Be warned though that in general catching an exception such as invalid pointer access is a bad idea (except perhaps to log what went wrong on the way out).  That represents a programming error and should be fixed, not worked around.
    • Marked as answer by Rob Pan Thursday, June 9, 2011 3:03 AM
    • Unmarked as answer by judeclarke Sunday, June 12, 2011 8:17 PM
    Friday, June 3, 2011 1:41 PM
  • My apologies for the late reply, I wanted to do some more testing and got caught up in other work.

     

    <blockquote>You are probably looking for __try/__catch/__finally.&nbsp; Be warned though that in general catching an exception such as invalid pointer access is a bad idea (except perhaps to log what went wrong on the way out).&nbsp; That represents a programming  error and should be fixed, not worked around.</blockquote>

    I am using try/catch/finally, but I wanted to extra backup encase there is any undesired behavior that comes up.

     

    <blockquote><p>SetUnhandledExceptionFilter should be working in debug version as well...now what happens in &nbsp;debug version? May be the debug version of CRT library installs another filter function on top of it. Also in some places of CRT i have seen it directly calling UnhandledExceptionFilter function( eg:&nbsp;inside abort() function )</p></blockquote>

    When I run this in Visual Studio, it will crash on the line in which the exception is thrown (the program execution will be halted). When I run the .exe, the function will be hit (I can tell because I print text).

    <blockquote><p>Also you can try <a href=""><strong>AddVectoredExceptionHandler</strong></a>&nbsp;function..</p></blockquote>

    I read over the docs for it, but I don't exactly see the advantage. Could you please explain?

    I have a test case for this code, here is a reference to the results I have been seeing. Maybe there is something coded wrong?

     

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

    LONG WINAPI MyFilter(EXCEPTION_POINTERS * /*ExceptionInfo*/)
    {
        std::cout << "An uncaught exception was detected!\n";

        // Ultimately causes Windows Error Reporting to be invoked.
        // Use EXCEPTION_EXECUTE_HANDLER to silently terminate the application.
        return EXCEPTION_EXECUTE_HANDLER;
    }

    int main()
    {
        SetUnhandledExceptionFilter(MyFilter);
        *(char volatile *)0 = 0;

        system("PAUSE");

        return(0);
    }

    • Edited by judeclarke Sunday, June 12, 2011 8:17 PM Formatting
    Sunday, June 12, 2011 8:16 PM
  • Simon said exactly what you needed to do. Access violations are async exceptions and are not handled by try/catch (there is no finally in the C++ exception handling). The VC compiler has had a second exception system which uses the keywords __try/__except/__finally. You can read about __try/__except and __try/__finally. Reading through the Structured Exception Handling section of the MSDN would also be a very good idea.

    A simple example of using __try/__except is

    #include <stdio.h>
    #include <Windows.h>
    
    int main()
    {
    	__try
    	{
    		*(char*)0 = 0;
    	}
    	__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
    	{
    		printf("Access violation caught\n");
    	}
    
    	return 0;
    } 
    

    Although if you read the sections linked, there is more information on using filter functions. That should clean up the __except line a lot.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.
    Visit my (not very good) blog at
    http://ccprogramming.wordpress.com/
    Sunday, June 12, 2011 11:07 PM
  • I read through http://msdn.microsoft.com/en-us/library/ms680657(VS.85).aspx which is how I find the code that I pasted. I wanted an extra catch layer just in case I did not catch an exception in a try/catch
    Sunday, June 12, 2011 11:18 PM
  • So what is wrong with just wrapping all of main in a __try/__except or a __try/__finally statement?
    For example.
    #include <windows.h>
    
    int filter(unsigned int code, _EXCEPTION_POINTERS* ep)
    {
      //do stuff
      return whatever;
    }
    
    int domain()
    {
      //do all of main stuff here
    }
    
    int main()
    {
      __try
      {
        return domain();
      }
      __except(filter(GetExceptionCode(), GetExceptionInformation())
      {
        //get here if an exception not handled in the try is caught
      }
    
      return 0;
    }
    

    You have to do it this way because only one type of exception handler is allowed per function. Exceptions are scope based, so if your inner try/catch doesn't catch it, that doesn't mean the outer one won't either. In fact, this is how the unhandled exception handler works. It is just an exception handler like the rest, and if an exception manages to travel out that far then it will be picked up by the unhandled exception handler.
    An example of how you can use the two together.
    #include <stdio.h>
    #include <Windows.h>
    
    int domain()
    {
    	try
    	{
    		throw 1;
    	}
    	catch(int exnum)
    	{
    		printf("exception caught, number %d\n", exnum);
    	}
    
    	try
    	{
    		*(char*)0 = 0;
    	}
    	catch(...)
    	{
    		printf("Unknown exception caught\n");
    	}
    	return 0;
    }
    
    int filter(unsigned int code, _EXCEPTION_POINTERS* ep)
    {
    	printf("Exception caught\n");
    	return EXCEPTION_EXECUTE_HANDLER;
    }
    
    int main()
    {
    	__try
    	{
    		return domain();
    	}
    	__except(filter(GetExceptionCode(), GetExceptionInformation()))
    	{
    		printf("Access violation caught\n");
    	}
    
    	return 0;
    } 
    

    So it is easy to do what you want without resorting to playing tricks with the unhandled exception handler.

    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.
    Visit my (not very good) blog at
    http://ccprogramming.wordpress.com/
    • Marked as answer by Rob Pan Thursday, June 16, 2011 2:33 AM
    • Unmarked as answer by judeclarke Thursday, June 16, 2011 7:08 PM
    Monday, June 13, 2011 11:27 AM
  • So what is wrong with just wrapping all of main in a __try/__except or a __try/__finally statement?
    It is not that I am trying to play tricks with the unhandled exception handler, it is that I am trying to use it correctly. I understand why you can just wrap everything in a try/catch, and that is fine. However, I would like know how to use the unhandled exception handler correctly, and why it is not triggering with the code I provided while running it through Visual Studio 2010 but will trigger when I run it alone in the .exe
    Thursday, June 16, 2011 7:08 PM
  • Does anyone know how I can catch a try catch in a SetUnhandledExceptionFilter while running through Visual Studio? The only time it gets called for me (code posted above) is when run outside visual studio.
    Saturday, June 25, 2011 8:06 PM
  • From what I gather you can't. The way exceptions work is

    A first chance exception notification gets delivered to the debugger if one is attached. (A debugger can handle this exception if it wants to.)

    It walks up the exception chain checking to see if one will handle it.

    If it is not handled a second chance exception notification is sent to the debugger, giving it another chance to handle it (this is where VS handles the exception).

    The system calls the unhandle exception handler.

    The reason why you don't get the unhandled exception handler being called when VS is because it takes the opportunity as the attached debugger to handle the exception at the second chance exception stage. By this stage the only thing left is the unhandled exception handler, and the information that VS gets out is more useful for developers than what the default handler does. There is also no way to switch off the exception handling feature either.

    If you don't mind losing all of the debugging capabilities you can start without debugging (ctrl + f5) in VS. But you will lose the source stepping capabilities too. However, when VS is attached as the debugger then the unhandled exception handler will never be called because VS will always handle the exception.


    This is a signature

    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.
    Visit my (not very good) blog at
    http://ccprogramming.wordpress.com/
    • Marked as answer by judeclarke Sunday, July 3, 2011 7:10 PM
    Saturday, June 25, 2011 8:36 PM