0

I have a Visual Studio 2008 C++ program where the program is wrapped in a __try/__except block to capture any SEH exceptions. The exception filter creates an error log and gives the user detailed instructions on how to submit a defect report.

Does the code within the filter need to be wrapped in another __try/__except block? If not, what happens if it excepts? If so, how should that be handled?

static int MyFilter( struct _EXCEPTION_POINTERS* ep )
{
    /*
    Code to log the exception information, and instruct the user 
    on how to submit a defect report. Should this be in another
    __try/__except block?
    */
    return EXCEPTION_EXECUTE_HANDLER;
}

int WINAPI _tWinMain( HINSTANCE hInstance, 
                      HINSTANCE /*hPrevInstance*/, 
                      LPTSTR lpstrCmdLine, 
                      int nCmdShow )
{
    int result = 0;

    __try
    {
        result = Execute( hInstance, lpstrCmdLine, nCmdShow );
    }
    __except( MyFilter( GetExceptionInformation() ) )
    {
        // empty
    }

    return 0;
}

Thanks, PaulH


Edit: If MyFilter raises an exception, then I get in to an infinite exception loop. So, it looks like it does need __try/__except handling. I'm looking at doing this:

static int MyFilter( struct _EXCEPTION_POINTERS* ep )
{
    __try 
    {
        /*
        Code to log the exception information, and instruct the user 
        on how to submit a defect report. 
        */

       // cause an exception
       int x = 0, y = 1 / x;
    }
    __except( EXCEPTION_EXECUTE_HANDLER ) { /*empty*/ }
    return EXCEPTION_EXECUTE_HANDLER;
}

In this case, the program should have an abnormal termination and exception should be passed up to the OS for it to deal with. Is that correct?

PaulH
  • 7,759
  • 8
  • 66
  • 143

2 Answers2

0

If you raise an exception in your filter you will end up in the filter method again. Your exception will be handled by the same __except block.
But there is no problem in using another __try __except block in your filter method.
Unfortunately I cannot give you any references to this. I just tried it my self and you can too. Just force an division by zero.
Usually I do not use SEH but the few times I did I had no issues in raising an exception in the filter method. But I did not find anything in the msdn when I looked for this.

mkaes
  • 13,781
  • 10
  • 52
  • 72
  • If `MyFilter` raises an exception, then I get in to an infinite exception loop. – PaulH Apr 06 '11 at 17:27
  • Of course you will if it is the same exception. As I said you will end up in the same __except block that will call your filter function again. If the filter throws in the first it will in the second and so on. – mkaes Apr 07 '11 at 09:42
  • I seem to remember that if an unhandled SEH exception occurs in an exception callback and it is not caught, that is treated as a double fault and the process is killed by the kernel. – Stewart Apr 07 '11 at 10:52
0

There are lots of things you need to be careful of when doing this. When your SEH handler runs, your process is in a completely unknown state and some of the things you try to do to instruct the user may fail. For example, if the exception was a stack overflow, there is very little you can do here. If you use a UI framework (MFC say) in here, it might be broken or in an inconsistent state because your app could have crashed mid way through some significant operation. If your app is multithreaded you need to know that those other threads will still be running when you get in to this filter, and handling that may take care.

If you really need to do this, one alternative approach is to have a watchdog process to do it.

Stewart
  • 3,978
  • 17
  • 20
  • Let's assume the code within the exception filter is entirely local to the filter (static) and uses no more UI then `::MessageBox`. Windows (and Windows Mobile) both have a watchdog process, but I'd like to give my app a chance to log an error before Dr. Watson gets to it. – PaulH Apr 06 '11 at 17:34
  • Sure, and that may work most of the time, but it doesn't always work. MessageBox, for example, creates a dialog and runs a modal message loop on your threads stack. If your stack is blown, that won't work. Another risk is that with a modal dialog such as a message box on screen, messages for windows created on your thread are still being pumped so your wndprocs will still potentially be getting called which means your normal app code can still run even though everything you do in your exception handler is "static". It isn't impossible to fix this stuff, but it is hard. – Stewart Apr 07 '11 at 10:46
  • Since you mention Windows Mobile (you didn't mention that before :)) my suggestion of a watchdog process there might not be such a good one because of the 32 process limit on CE 5. A service or driver to do that might be more effective since services and devices are always running anyway if the process limit is a problem. – Stewart Apr 07 '11 at 10:49