私は、スタックオーバーフロー例外をスローする方法に対して再帰的な呼び出しを受けました。最初の呼び出しはtry catchブロックで囲まれていますが、例外はキャッチされません。
スタックオーバーフロー例外は特別な方法で動作しますか?例外を正しくキャッチ/処理できますか?
注意:該当する場合:
メインスレッドでは例外はスローされません
コードが例外をスローしているオブジェクトは、Assembly.LoadFrom(...)によって手動でロードされます。CreateInstance(...)
2.0以降では、StackOverflow例外は以下の状況でしか捕捉できません。
Starting with 2.0 ...
、私が珍しいのは、彼らがSOを捕まえられないようにしている理由と、それがどのように可能だったか1.1
(あなたはあなたのコメントでそれを述べました)? - M.kazem Akhgary
正しい方法はオーバーフローを修正することですが、....
あなたは自分自身にもっと大きなスタックを与えることができます: -
using System.Threading;
Thread T = new Thread(threadDelegate, stackSizeInBytes);
T.Start();
System.Diagnostics.StackTrace FrameCountプロパティを使用して、使用したフレームをカウントし、フレーム制限に達したときに独自の例外をスローすることができます。
または、残りのスタックのサイズを計算し、それがしきい値を下回ったときに独自の例外をスローすることができます。
class Program
{
static int n;
static int topOfStack;
const int stackSize = 1000000; // Default?
// The func is 76 bytes, but we need space to unwind the exception.
const int spaceRequired = 18*1024;
unsafe static void Main(string[] args)
{
int var;
topOfStack = (int)&var;
n=0;
recurse();
}
unsafe static void recurse()
{
int remaining;
remaining = stackSize - (topOfStack - (int)&remaining);
if (remaining < spaceRequired)
throw new Exception("Cheese");
n++;
recurse();
}
}
ただチーズをキャッチ。 ;)
Cheese
具体的にはほど遠いです。行きますthrow new CheeseException("Gouda");
- C.Evenhuis
上のMSDNページからStackOverflowExceptions:
以前のバージョンの.NETでは フレームワーク、あなたのアプリケーションは StackOverflowExceptionオブジェクトをキャッチ (たとえば、 無制限の再帰)しかし、それは 練習は現在お勧めできません 重要な追加コードが 確実にスタックをキャッチするために必要 例外をオーバーフローさせて続行 プログラムの実行
.NET Frameworkから始める バージョン2.0、StackOverflowException オブジェクトをtry-catchでキャッチすることはできません ブロックし、対応するプロセスは デフォルトで終了します。その結果、 ユーザーは自分のコードを書くことをお勧めします スタックを検出して防止する オーバーフロー。たとえば、 アプリケーションは再帰、使用に依存 カウンタまたは状態条件 再帰ループを終了します。注意 それをホストするアプリケーション 共通言語ランタイム(CLR)は CLRがアンロードするように指定します。 スタックが置かれているアプリケーションドメイン オーバーフロー例外が発生し、 対応するプロセスは続行します。にとって 詳細については、を見てください ICLRPolicyManagerインターフェースおよび 共通言語ランタイムのホスティング
何人かのユーザーがすでに言ったように、あなたは例外を捕まえることができません。しかし、それがどこで起こっているのかを見つけるのに苦労しているのであれば、あなたはそれが投げられたときに壊れるようにビジュアルスタジオを設定したくなるかもしれません。
それには、[デバッグ]メニューから[例外設定]を開く必要があります。古いバージョンのVisual Studioでは、これは[デバッグ] - [例外]にあります。新しいバージョンでは、[デバッグ] - [Windows] - [例外設定]にあります。
設定を開いたら、[共通言語ランタイム例外]、[システム]の順に展開し、下にスクロールして[System.StackOverflowException]をオンにします。それからあなたは呼び出しスタックを見て、呼び出しの繰り返しパターンを探すことができます。これにより、スタックオーバーフローの原因となっているコードをどこで修正すればよいかがわかります。
上記のように、プロセス状態が破損しているためにシステムによって発生したStackOverflowExceptionをキャッチすることは不可能です。しかし、例外としてイベントとして気付く方法があります。
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx.NET Frameworkバージョン4以降では、イベントハンドラーがセキュリティ上重要でHandleProcessCorruptedStateExceptionsAttribute属性を持たない限り、スタックオーバーフローやアクセス違反など、プロセスの状態を破損する例外に対してこのイベントは発生しません。
それにもかかわらず、あなたのアプリケーションはevent-functionを終了した後に終了します(非常に汚い回避策は、このイベントの中でアプリを再起動することでした、そうしないで、決してしないでしょう)。しかし、ログ記録には十分です。
.NET Frameworkバージョン1.0および1.1では、メインアプリケーションスレッド以外のスレッドで発生した未処理の例外はランタイムによってキャッチされるため、アプリケーションは終了しません。したがって、アプリケーションが終了せずにUnhandledExceptionイベントが発生する可能性があります。 .NET Framework Version 2.0以降では、このようなサイレント障害による累積的な影響として、パフォーマンスの低下、データの破損、ロックアップなど、デバッグが困難であったため、子スレッドでの未処理の例外に対するこのバックストップが削除されました。ランタイムが終了しないケースのリストなど、詳細については、管理スレッドでの例外を参照してください。
CLR 2.0からのはい、スタックオーバーフローは回復不可能な状況と見なされます。だからランタイムはまだプロセスをシャットダウンします。
詳しくはドキュメントをご覧ください。http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx
StackOverflowException
デフォルトでプロセスを終了します。 - Brian Rasmussen
できません。 CLRはあなたをさせません。スタックオーバーフローは致命的なエラーであり、回復することはできません。
ほとんどの投稿が説明しているようにあなたはできません、私は別の分野を加えてみましょう:
多くのWebサイトでは、これを回避する方法は別のAppDomainを使用することで、ドメインがアンロードされると言われています。 CLRのデフォルトの動作によってKillProcessイベントが発生し、デフォルトのAppDomainがダウンするため、これは絶対に間違っています(CLRをホストしている場合を除く)。
それは不可能であり、そして正当な理由のために(一つには、それらすべてのキャッチについて考える(例外){})。
スタックオーバーフロー後も実行を継続したい場合は、別のAppDomainで危険なコードを実行してください。元のドメインに影響を与えることなく、オーバーフロー時に現在のAppDomainを終了するようにCLRポリシーを設定できます。
Assert.Fail
代わりに。だから真剣に - 私たちはこれについてどうやって行きますか? - BrainSlugs83