Search code examples
c++seh

How to handle SEH exception on a global level


I wanted to catch SEH exception globally i.e. if a SEH exception occurs in a thread of an object of ClassB called in ClassA, is it possible to catch the SEH exception in Main (ClassA instance is called in Main)?

I have been using SetUnhandledExceptionFilter in Main to catch these SEH exceptions but I failed to catch for this case particularly. Since there are multiple classes and program is multi-threaded, I am looking for options to catch it on a global level. (Note: The compiler has been set to /EHa flag.)

  MyUnhandledExceptionFilter(Exception ptr){

     //Handle SEH exception 
  }


    ClassA
    {
     //Some stuff ...
     ClassB objB.DoSomething();
    }


    ClassB{

      DoSomething(){
      CreateThread(Threadfunc)
      };

      ThreadFunc(){
         //SEH exception occurs;
      }
    }



   int main(){
    SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
    try
   {
     ClassA objA::run();

    }
   catch(exception ex){
      //Log here 
    }
  }


Solution

  • Have a look at Vectored Exception Handling:

    Vectored exception handlers are an extension to structured exception handling. An application can register a function to watch or handle all exceptions for the application. Vectored handlers are not frame-based, therefore, you can add a handler that will be called regardless of where you are in a call frame. Vectored handlers are called in the order that they were added, after the debugger gets a first chance notification, but before the system begins unwinding the stack.

    For example:

    #include <windows.h>
    
    LONG WINAPI MyVectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
    {
        // Log here ...
    
        return EXCEPTION_CONTINUE_SEARCH; // or EXCEPTION_CONTINUE_EXECUTION
    }
    
    class ClassB
    {
    public:
        void DoSomething() {
            HANDLE hThread = CreateThread(NULL, 0, &ThreadFunc, NULL, 0, NULL);
            if (hThread) CloseHandle(hThread);
        }
    
        static DWORD WINAPI ThreadFunc(LPVOID) {
            //SEH exception occurs
        }
    };
    
    class ClassA
    {
    public:
        ClassB objB;
    
        void run() {
            // Some stuff ...
            objB.DoSomething();
        }
    };
    
    int main(){
        AddVectoredExceptionHandler(0, &MyVectoredExceptionHandler);
        ClassA objA;
        objA.run();
        //...
    }