この質問にはすでに答えがあります。
私はこれが非常に曖昧であることを知っています、しかしこれは私が集めることができるすべてです。誰かがこれがどのように起きているのかについての洞察を持っているといいのですが。
私は、Visual Studio 2012で構築された、Win 7 64ビットマシン上で実行している64ビットプログラムを持っています。
それは(dllとしてコンパイルされた)別のプロジェクトにあるクラスを使用します。そのクラスは、スタックオーバーフローを引き起こす可能性があるバグの多いイテレータを持っています。そのバグのある反復子を呼び出す操作は、タスクを通じて呼び出されます。
だから私のプログラムでは、コードはこのようになります:
new Task(()=>{
try
{
DoWork(); //<-- buggy iterator is called inside
}
catch (Exception ex)
{
//Exception reported to user
}
}).Start();
コードは毎回同じデータに対して実行され、ランダム変数やguidの生成は含まれていないため、毎回同じ出力を生成する必要があります。
ほとんどの場合、それはとクラッシュします不明なモジュールで発生したStackOverflowException(たとえ私が実際にそれが正確に起こる場所を知っているとしても)。それが起こるならば、私はオーバーフローが起きたコードの点を見ることができません、そしてtry-catchブロックは何もしません!プログラムを実行し続けることができません(デバッグなしで実行すると、「プログラムを閉じる必要があったため、解決策をオンラインで確認できます」システムウィンドウ)。
さて、時々それは例外をキャッチする(例外を引き起こしたコードの正しい場所が示される)。これはランダムですが、より頻繁にタスクを中断すると(タスクの実行中にタスクにブレークポイントをランダムに挿入するように)より多く発生するようです。
しかし、私はまだ申請を続けることができません。 StackOverflowExceptionをキャッチするはずのtry-catchブロック内で例外が発生したとしても(StackOverflowExceptionはExceptionに含まれているため、キャッチすることになっています - C#では両方をキャッチできず、SOEが既にEに含まれていることを明示します)。
try-catchブロック内で意図的なスタックオーバーフローを発生させる小さなプログラムを作成してみました。「プログラムを閉じる必要があったため、解決策をオンラインで確認できます」それを正しく処理する代わりに、システムウィンドウを表示してください。これがコードです:
private bool Overflow()
{
return Overflow();
}
private void button1_Click(object sender, EventArgs e)
{
try { Overflow();}
catch (StackOverflowException ex) { }
}
したがって、いくつか質問があります。
質問1:
StackOverflowExceptionsをキャッチすることは可能ですか?どうすればいいのですか?
質問2:
dll(同じソリューション内の他のプロジェクト)内でスタックオーバーフローが発生した場合、VS 2012デバッガに "不明なモジュール"と思わせる原因は何ですか?
質問3:
部族の楽器を使って奇妙なマジックダンスをすると、それほど頻繁に行われないのはなぜですか。 (つまり、進行中のプログラムをランダムに中断することを意味します)
全体的に見て、何が起こっているのでしょうか。
前もって感謝します
あなたはキャッチすることは許可されていませんリアルスタックオーバーフロー例外、それが動作しない理由です。
また見なさいこの討論。
私はあなたの2番目の質問に答えることはできません、「プログラムは本当に混乱している」と言うこと以外に。
3番目の質問です。それは別のスレッドで実行されているため、実行されるコードの量はプログラムをいつ中断したかによって異なります。私はあなたがこれの底に達することができる唯一の方法がいくつかの退屈な行ごとのデバッグ、または多くのDebug.WriteLine()を通してであると思う。
1).NET Frameworkバージョン2.0以降、StackOverflowExceptionオブジェクトはtry-catchブロックで捕捉できず、対応するプロセスはデフォルトで終了します。そのため、スタックオーバーフローを検出して防止するためのコードを書くことをお勧めします。たとえば、アプリケーションが再帰に依存している場合は、カウンタまたは状態条件を使用して再帰ループを終了します。共通言語ランタイム(CLR)をホストするアプリケーションは、スタックオーバーフロー例外が発生するアプリケーションドメインをCLRがアンロードし、対応するプロセスを続行させるように指定できます。詳しくは、ICLRPolicyManagerインターフェースおよびホスティングの概要を参照してください。 (http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx)