4

私はネイティブファイバー/コルーチンの実装に取り​​組んでいます–かなり標準的で、ファイバーごとに個別のスタックが割り当てられ、コンテキストを切り替えるために、レジスタがソースコンテキストスタックにプッシュされ、ターゲットスタックからポップされます。それはうまく機能しますが、今私は少し問題にぶつかりました:

ファイバー内で動作するSEHが必要です(プログラムが終了したり、ファイバーの最後のスタックフレームまで例外が処理されないときに奇妙なことが起こり始めても問題ありません)。FS:[0]コンテキストスイッチ中に(FS:[4]および、明らかに)保存/復元しFS:[8]、最初にFS:[0]をに設定します(コンテキスト0xFFFFFFFFスイッチの後に設定された例外ハンドラーがチェーンのルートになるように)。

正確には、テストしたすべての非サーバーWindows OSで動作します。問題は、Windows Server2008および2008R2で例外チェーン検証(SEHOP、SEH上書き保護)機能がデフォルトで有効になっていることです。これによりRaiseException、元のハンドラーがチェックされます。 (ntdll.dllのどこかに)はまだチェーンのルートであり、ハンドラーがインストールされていないかのようにプログラムをすぐに終了します。

したがって、検証コードを満足させるために、スタック上に適切なルートフレームを構築するという問題に直面しています。それを行うために呼び出すことができる(隠された?)API関数はありますか、それともRtlDispatchException友人を幸せに保つために何が必要かを理解し、適切な_EXCEPTION_REGISTRATIONエントリを自分で作成する必要がありますか?間違ったアドレスにあるため、作成スレッドからWindows提供のものを再利用することはできません(SEH実装は、ハンドラーアドレスがとで指定された境界内にあるかどうか、場合によってはアドレスの順序が一貫しているかどうかもチェックしFS:[4]ますFS:[8]) )。

ああ、私はWinAPIファミリーの関数に頼らないことを強く望んでいます。CreateFiber

4

1 に答える 1

1

コメントで述べた、をEXCEPTION_REGISTRATION指す偽のエントリを生成するアプローチはntdll!FinalExceptionHandler、実際に機能しているようです。少なくとも、これは現在Dランタイムにあるものであり、これまでのところ問題の報告はありません。

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

于 2012-11-11T02:45:00.453 に答える