Question

I'm working on a native fiber/coroutine implementation – fairly standard, for each fiber, a separate stack is allocated, and to switch contexts, registers are pushed onto the source context stack and popped from the target stack. It works well, but now I hit a little problem:

I need SEH to work within a fiber (it's okay if the program terminates or strange things start to happen when an exception goes unhandled until the fiber's last stack frame, it won't). Just saving/restoring FS:[0] (along with FS:[4] and FS:[8], obviously) during the context switch and initially setting FS:[0] for newly allocated fibers to 0xFFFFFFFF (so that the exception handler set after the context switch will be the root of the chain) almost works.

To be precise, it works on all non-server Windows OSes I tested – the problem is that Windows Server 2008 and 2008 R2 have the exception chain validation (SEHOP, SEH overwrite protection) feature enabled by default, which makes RaiseException check if the original handler (somewhere in ntdll.dll) is still the root of the chain, and immediately terminates the program as if no handlers were installed otherwise.

Thus, I'm facing the problem of constructing an appropriate root frame on the stack to keep the validation code happy. Are there any (hidden?) API functions I can call to do that, or do I have to figure out what is needed to keep RtlDispatchException and friends happy and construct the appropriate _EXCEPTION_REGISTRATION entry myself? I can't just reuse the Windows-supplied one from the creating thread because it would be at the wrong address (the SEH implementation also checks if the handler address is in the boundaries given by FS:[4] and FS:[8], and possibly also if the address order is consistent).

Oh, and I'd strongly prefer not to resort to the CreateFiber WinAPI family of functions.

Was it helpful?

Solution

The approach I mentioned in the comments, generating a fake EXCEPTION_REGISTRATION entry pointing to ntdll!FinalExceptionHandler seems to work in practice indeed – at least, that's what we have in the D runtime now, and so far there have been no reports of problems:

https://github.com/D-Programming-Language/druntime/blob/c39de42dd11311844c0ef90953aa65f333ea55ab/src/core/thread.d#L4027

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top