Search code examples
windowsexceptioncrash-reportssehboost-context

SetUnhandledExceptionFilter does not work with boost context


I'm using make_fcontext and jump_fcontext from boost context to achieve userspace context switching. I use another library to catch and report application crashes. I found these 2 does not work together on Windows.

The crash library calls SetUnhandledExceptionFilter during startup time to setup an exception handler to catch unhandled exceptions from the process. It then processes the exception record for crash reporting. This works most of the time and there is no other exception handling in my application.

However, when a crash (hardware/software exception) happened in a thread running on a boost context, I found that the set exception handler was not triggered. Seems like instead the kernel launched WerFault.exe which generates a minidump under C:\Windows\System32\config\systemprofile\AppData\Local\CrashDumps.

It seems like running on a boost context affects the kernel's ability to find or use the superseded global unhandled exception filter. When running on a boost context, the bottom of the stack looks like:

...
my_context_function
make_fcontext+0x76

While running on a normal Windows stack:

...
my_thread_start_function
KERNEL32!BaseThreadInitThunk+0x14
ntdll!RtlUserThreadStart+0x21

I'm wondering what could possibly go wrong here. I'm new to Windows and SEH so apologize in advance if the question does not make sense.


Solution

  • I think this is a limitation of default context, which does not do everything that Windows does, which is not likely to be fixed for you. If you want full support of Windows stuff, you probably should switch to Windows Fibers. Looks like Boost Context supports them.

    The drawback of using Windows Fiber could be worse performance.

    If this matters for you, you probably have to use fast context, and have your own SEH frame:

    __try 
    { 
       ... 
    } 
    __except(UnhandledExceptionFilter(GetExceptionInformation()) 
    {
    }
    

    Sure this is not guaranteed to repeat Windows internal handling exactly. But you only have to do what matters for you, not necessarily repeating the whole Windows internals.

    The SEH frame could be centralized in a wrapper function. Alternatively, you can try AddVectoredContinueHandler (as far as I remember, vectored continue handler is called after frame-based handlers, unlike AddVectoredExceptionHandler which is called before them).