我正在研究原生光纤/协程实现——相当标准,对于每个光纤,分配一个单独的堆栈,并且为了切换上下文,寄存器被推送到源上下文堆栈并从目标堆栈中弹出。它运作良好,但现在我遇到了一个小问题:
我需要 SEH 在纤程内工作(如果程序终止或奇怪的事情开始发生,直到纤程的最后一个堆栈帧之前未处理异常,这没关系,它不会)。只是在上下文切换期间保存/恢复FS:[0]
(显然与FS:[4]
and一起FS:[8]
)并最初为新分配的纤程设置 FS:[0] 0xFFFFFFFF
(以便在上下文切换后设置的异常处理程序将成为链的根)几乎可以工作。
准确地说,它适用于我测试过的所有非服务器 Windows 操作系统——问题是 Windows Server 2008 和 2008 R2 默认启用了异常链验证(SEHOP、SEH 覆盖保护)功能,这使得RaiseException
检查原始处理程序是否(在 ntdll.dll 中的某处)仍然是链的根,并立即终止程序,就好像没有安装任何处理程序一样。
因此,我面临着在堆栈上构建适当的根框架以保持验证代码满意的问题。是否有任何(隐藏的?)API 函数我可以调用来做到这一点,还是我必须弄清楚需要什么才能让RtlDispatchException
朋友开心并_EXCEPTION_REGISTRATION
自己构建适当的条目?我不能只重用创建线程中的 Windows 提供的地址,因为它会位于错误的地址(SEH 实现还检查处理程序地址是否在 and 给出的边界内FS:[4]
,FS:[8]
并且还可能检查地址顺序是否一致)。
哦,我强烈不希望诉诸CreateFiber
WinAPI 系列函数。