2012-10-30 12 views
13

Windows SEH例外からC++例外をデコードできますか? (?もしそうなら、どのように)私が印刷したい未処理のC++の例外が発生した場合

  1. C++例外
  2. スタックトレースのメッセージ(what())。

スタックトレースを取得するためには、私はStackWalkerライブラリと組み合わせてSetUnhandledExceptionFilterを使用しています:私はちょうど罰金印刷するスタックトレースを得ているが、今whatをされてき

struct FooStackWalker : StackWalker 
{ 
    virtual void OnCallstackEntry(CallstackEntryType, CallstackEntry &entry) override 
    { 
     std::cerr << entry.lineFileName << " (" << entry.lineNumber << "): " << entry.undFullName << std::endl; 
    } 
}; 

LONG WINAPI UnhandledExceptionHandler(LPEXCEPTION_POINTERS pointers) 
{ 
    FooStackWalker walker; 
    walker.ShowCallstack(::GetCurrentThread(), pointers->ContextRecord); 
    ::TerminateProcess(::GetCurrentProcess(), 1); 
} 


int main() 
{ 
    ::SetUnhandledExceptionFilter(UnhandledExceptionHandler); 
} 

難しい

終了前にこのメンバー関数を呼び出すために、C++例外としてSEH例外をデコードする方法はありますか?

+0

あなたは3つのExceptionInformation単語を正しく取得するでしょう。 2ndは例外オブジェクトへのポインタです。あなたはそれを解釈する希望がありません.C++でのリフレクションなどはありません。 * catch *キーワードによって生成される例外フィルタは非常に重要です。 –

+0

@ハンス:スローされるものが常に 'std :: exception'(多くのコードベースで当てはまります)から導かれると仮定すると、それは解釈できませんか? 'std :: exception'を取得したら、必要に応じて特定の例外タイプに' dynamic_cast'を実行できます。 –

+0

* what * exceptionにキャストしますか?それが鍵です。あなたは*何*を得るかもしれません。 –

答えて

2

例外の詳細を示しているC++マシンを使用しないのはなぜですか?それはSEHフィルタと排他的ではありません(で、SetUnhandledExceptionFilterと排他的です)。

int main() 
{ 
    try { 
     return cppexcept_main(); 
    } 
    catch (const std::exception& e) 
    { 
     //use e.what() 
    } 
} 

int cppexcept_main() 
{ 
    __try { 
     return application_main(); 
    } 
    __except(GrabStackTrace(GetExceptionInformation()), EXCEPTION_CONTINUE_SEARCH) { 
     /* never reached due to EXCEPTION_CONTINUE_SEARCH */ 
    } 
} 
2

:ご質問が誤解されました。私は、C++の例外に対する答えが何であるかについてはっきりと言うことはできませんが、答えは「いいえ」と合理的に確信しています。私は、SEH(アクセス違反など)によって引き起こされた未処理の例外とキャッチされていないC++の例外を区別する方法や、さまざまな種類のC++例外を区別する方法はないと考えています。馬はすでにその馬に納屋を残しています。以下

オリジナルの答えは:


いいえ、SEH例外がwhatを持っていないため。 std::exceptionではありません。 This MSDN exampleは、SEH例外をC++例外としてキャッチしようとしているときは、省略記号(...catchハンドラでしか捕捉できないと言います。 _set_se_translatorを使用して、SEH例外をC++例外に変換する独自の関数を定義することができますが、その時点で別の場所で同じ情報から自分のwhatを生成しているだけです(さらに、あなたはUnhandledExceptionFilterからそれを得ることができます)。

LPEXCEPTION_POINTERS structureに必要な情報がすべてあります。アクセス違反が発生した場合、pointers->ExceptionRecord->ExceptionCodeEXCEPTION_ACCESS_VIOLATION(0xC0000005)になります。それが起こった場合は、NumberParametersExceptionInformation変数を調べて、読み取りまたは書き込み違反か、アクセスしようとしたアドレスかを調べることができます。

+0

いいえ、私はSEH例外をC++例外に逆向きにしたいと思います。もちろん、SEH例外が実際にはC++例外(MSVC++は例外コード '0xE06D7363'を使用しているようです)であれば、何の変換も失敗したり、地獄に行くように言われたりします。とにかくスタックトレースを印刷しようとしています - アクセス違反などの後も実行を続行しないでください)。 –

+0

(これは普通のC++の 'catch'の中でこのようなことをするのがうれしいことに注意してください。しかし、その時点でスタックは解き放たれているので、投げるポイントのスタックを印刷することは不可能です) –

+0

http:0xE06D7363:http ://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx –

関連する問題