C++のコードでNULL参照や0割りなどを行うと例外が発生しますよね。
これらは構造化例外といって、try{}catch(...){}で囲ってキャッチ出来ません。
throw 0;とか書いて、任意の場所で例外を発生させることが可能です。
try{}catch(...){}で囲ってキャッチすることは可能ですが、どこから投げられたかを知る手段はありません。
今回は例外が発生した時に、極力原因に辿り着けるよう情報を取得し、ログに出力する機構についてまとめます。
C++ のリソースを C# で使う事があると思いますが、C# で例外を受け取った時に
「外部コンポーネントが例外をスローしました」となる場合について
C# 側からは原因の特定は出来ません。
C++側にて例外が発生したことを知るすべがあります。
例外ハンドラの登録です。
try{}catch(...){}で囲ってキャッチ出来ない構造化例外の発生も知ることができます。
SetUnhandledExceptionFilter(VectoredExceptionHandler);
VectorExceptionHandlerの実装詳細を次に示します。
出力されるログから、どんな例外がどこで発生したのか特定できるはずです。
自分でthrowする場合は、直前のスタックトレースを出してログに吐いてからthrowしてください。
誰かがthrowして、ハンドリングされてないのが来た場合は C++ Exception としかわかりません。
そういうのが出てきた場合は開発元に問い合わせて下さい。
(throwする前にログを吐けとか、throwした例外の型を教えろとか)
ハンドラの設定には他にも PVOID h = AddVectoredExceptionHandler (0, VectoredHandler ); というのがあります。
C# Form, WPF つまり GUI? から使用するとハングするようなので、取り扱いには注意が必要。
参考ページ
Exception Handling - Inform your users! Part 2
【落ちるバグが怖くなくなる】Windows C++でコールスタックを取得する
Don't run managed code from the VectoredExceptionHandler
2013/06/01 最終更新