5

私は現在、実行時にマシン コードを生成する C++ でコンパイラを作成しようとしています。ただし、現在、安全な例外処理 (/SAFESEH でコンパイル) を有効にしようとしています。カスタム例外ハンドラはデバッグ モードで動作していますが、同じコードをリリース モードで実行すると、プロセスが終了してしまいます。

/SAFESEH:NO を使用してコードをコンパイルすると、リリース モードでもすべて正常に動作するため、カスタム例外ハンドラーをそのまま登録できないことが問題であると確信しています。

私のカスタム例外ハンドラーは私の他の C++ コードで記述されており、内容を含む .asm ファイルをプロジェクトに追加することで例外ハンドラーとして登録しようとしました。

.386
.model flat
_MyExceptionHandler@16 proto
.safeseh _MyExceptionHandler@16
end

ここで説明されているように。次に、asm ファイルが /safeseh オプション (とりわけ) を使用してアセンブルされました。

私のハンドラー関数には現在、次の宣言があります。

extern "C" EXCEPTION_DISPOSITION __stdcall MyExceptionHandler(struct
_EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, struct 
_CONTEXT *ContextRecord, void * DispatcherContext);

この関数を例外ハンドラとして登録する正しい方法は何ですか?

ご提案ありがとうございます。

4

3 に答える 3

4

私はついに問題を説明するページを見つけました:ここに。ただし、ページのコードサンプルは、変更しないと機能しませんでした。

問題は、外部プロシージャを例外ハンドラとして登録すると意図したとおりに機能しないため、代わりにローカルアセンブリプロシージャを例外ハンドラとして登録する必要があることです。

前に述べたページで与えられた例に基づいて、これは私が最終的に得たものです:

.386
.model flat, stdcall
option casemap :none

extern MyExceptionHandler@16:near

MyExceptionHandlerAsm proto
.SAFESEH MyExceptionHandlerAsm

.code
MyExceptionHandlerAsm proc
    jmp MyExceptionHandler@16
MyExceptionHandlerAsm endp
end

これは機能しているように見えますが、おそらく最も洗練されたソリューションではありません。例:C / C ++からMyExceptionHandlerAsmを参照するときにリンクエラーを回避するには、次のように宣言する必要がありました。

extern "C" int __stdcall MyExceptionHandlerAsm();

パラメータの数がMyExceptionHandlerの数と一致しないため、誰かがC /C++からMyExceptionHandlerAsmを呼び出そうとするとクラッシュします。

于 2012-08-19T10:24:37.613 に答える
1

MSDNのドキュメントから、ASM が正しいようです。/safesehにオプションを追加しましたml.exeか?

于 2012-08-18T19:56:18.580 に答える
0

ExceptionHandler関数のシグネチャは実際には次のとおりです。

typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
    __in struct _EXCEPTION_RECORD *ExceptionRecord,
    __in PVOID EstablisherFrame,
    __inout struct _CONTEXT *ContextRecord,
    __inout PVOID DispatcherContext
    );

このMSDNページを参照してください。同じ例外ルーチンが32ビットウィンドウに使用されるため、ドキュメントでx64について言及されているという事実は無視してください。

于 2012-08-20T02:50:26.253 に答える