3

Windows の構造化例外を処理するコードを書いています (私の場合は、_set_se_translator()それらを C++ 例外に変換するために使用しています)。

私が気になっているのは、例外が発生したときに渡される例外情報でポインタが多用されていることです。構造体へのポインタが渡されます_EXCEPTION_POINTERS。これには、他の 2 つの構造体へのポインターが含まれています。そのうちの 1 つには、そのオブジェクトを基本的にリンク リストにする別のポインター フィールドが含まれている可能性があります。

これらすべてのポインターの背後にあるメモリはどこに割り当てられますか? 割り当て解除の責任は誰にありますか? 私ではない場合、データが有効であるとどのくらいの期間期待できますか?また、リークを回避するにはどうすればよいですか?

現在、私の se トランスレータ ルーチンは次のようになっています。

void se_translator(unsigned int exception_code, struct _EXCEPTION_POINTERS* exception_information) {
    _clearfp();
    throw se_exception(exception_code, exception_information);
};

そして、ここで心配なのは、内部で指されているすべてのデータがexception_information私の es 内の範囲外にcatchなるか、何らかの形ですべてが漏洩することです。

これについて説明しているドキュメントがある場合は、それを指摘したいと思います。

4

1 に答える 1

4

スタック。例外レコードは、例外が発生する前にスタックにプッシュされます。Win32™ 構造化例外処理の深さに関する短期集中コースを参照してください。EXCEPTION_POINTERS は、SEH の EXCEPTION_REGISTRATION に対する Visual C++ 固有の拡張機能です。

拡張された EXCEPTION_REGISTRATION 構造体のすぐ下に、Visual C++ は 2 つの追加の値をプッシュします。すぐ下の DWORD には、EXCEPTION_POINTERS 構造体 (標準の Win32 構造体) へのポインター用のスペースが予約されています。これは、GetExceptionInformation API を呼び出したときに返されるポインターです。

実際、SEH はスタック構造のみを使用します。これは、例外条件下では最も信頼性の高い唯一のメモリ アロケータであるためです。ファウルプルーフではありません (例外レコード用のスタックスペースがない場合、プロセスはトレースなしで消滅します) が、最高です。

 throw se_exception(exception_code, exception_information);

exception_information私のキャッチ内の範囲外になります

いいえ、そうはなりません。スタックは次のようになります。

somefunction_x::`catch block
DispatchException
RaiseException 
<- exception record is here ->
frame that triggered the SEH raise (c++ throw, AV, stack overflow etc)
caller
somefunction_x
caller
threadentrypoint

しかし、あなたがしていることは非常に異常です。通常、トランスレーターは AV ( ExceptionCodeis EXCEPTION_ACCESS_VIOLATION) のような非 c++ 例外を特定の c++ 例外に変換します。例外レコードを検査し、ExceptionCode適切な C++ 型付き例外を発生させます。

于 2012-09-19T20:17:55.393 に答える