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