2

MSVC 2005 でコンパイルされた大規模なマルチスレッド アプリケーションで謎のクラッシュが発生し、それを特定するのに苦労しています。回避策が必要です。問題を 1 つの関数に切り分けて、次の行に沿って何かを行うことができれば:

__try
{
  FunctionWhichMayCauseCrash();
}
__except ( [filter expression] )
{
  Recover();  // magic - this allows us to prevent crash and continue
}

理論的には、それは私にとって良い考えのように思えます。実際には、何人かの人々 (ここのLarry Ostermanやここの Doug Harrison など) は、非常に悪い考えのように聞こえます。

現実のチェック: 私のプログラムは構造化された例外を生成していますが、どこにあるのかわかりません。Hans Dietrich の XCrashReport の一部(それ自体が使用) を使用__try/__exceptして、これらの例外の原因を突き止めようとしていますが、今のところうまくいきません。一部の共有リソースが適切にロックされていない可能性が高いため、あるスレッドが別のスレッドの下から敷物を引っ張っているため、多かれ少なかれランダムな場所でアクセス違反が発生しています。

そのようなメカニズムが私のプログラムのクラッシュを防ぐ実用的な妥協点はありますか? 私が選択したクラッシュ回復メカニズムが、他の人が警戒しているものを使用していることを心配する必要がありますか?

明確化:プログラムのクラッシュによる極端な混乱のため、最終的な恒久的な解決策ではなく、クラッシュを防ぐ回避策を探します。__try/__exceptカーペットの下で問題を一掃するために使用するつもりはありません。私は単に、それが一部の人が言うほど危険なのか、それとも注意して使用する必要がある正当なツールなのかを理解しようとしているだけです. 一部の人々の話し方によると、自分のコードを/EHadefined でコンパイルしようとした瞬間に、私のコンピューターはおそらく炎上するでしょう。/EHaを使用した方がよい、または同じことになると人々が言うのか、それとも両方とも本当に悪い考えなの_set_se_translatorかを知りたいです。try/catch(...)

明確化 2:デバッグの助けは必要ありません :-) むしろ、SEH と C++ を混在させることの意味を理解する助けが必要です。私の評判の低さは、C++ の新しさではなく、フォーラムの新しさを示しています。C++ プログラムに SEH コンストラクトを導入することの意味に人々が注目するよう促すために、私は自分のアプリケーションを問題から意図的に抽象化しました。それはうまくいきませんでした :-) たまたま、私のアプリケーションにはオブジェクトのパイプラインがあり、オブジェクトの破損を検出した場合は、それらのパイプラインを簡単にダンプできます。したがって、私の魔法のRecover()機能は、聞こえるほど魔法のようなものではなく、破損がヒープのごく一部に限定される可能性が十分にあります。それで...質問に戻ります:使用は__try/__except賢明ですか?

4

2 に答える 2

1

行う。いいえ。行う。これ。

リンクからの Doug Harrison のコメントに完全に同意できます。SEH の使用は非常に危険です。なぜなら、コードに (おそらく重大な) エラーを隠してしまうからです。

例外が発生する可能性がある場所について非常に具体的な考えがある場合は、一時的にコードに SEH ブロックを追加すると追跡に役立つ場合がありますが、そうではないと思われます-スタックが破損しています.

プログラムの大部分に SEH ブロックを追加しないことをお勧めします。なぜなら、SEH ブロックを追加すると、プログラムがクラッシュするのを防ぐだけで、問題を隠すことができるからです。クラッシュは非表示になりますが、アプリケーションの状態が破損しているかどうか (およびその程度) はわかりません。破損したデータがデータベースに保存された場合、クライアントはこれであまり役に立ちません。

別のSEH の質問があります。役に立つと思います。

SEH を使用しようとする代わりに、時間とエネルギーを使って問題を解決しようとします。WinDbg を使用すると (クラッシュからのミニダンプがある場合)、高速化できます。よくわからない場合は、ここにチュートリアルがあります。

私は SEH の専門家ではないので、他の人がより詳細なアドバイスを提供できるかもしれませんが、SEH ソリューションは非常に最後の手段としてしか試していません。

于 2013-02-05T03:19:19.763 に答える
0

問題は、SEH が呼び出されるまでに、アプリが完全に停止していることです。 CRT によってユーザー空間で行われたすべてのものを含め、アクセス可能な (使用されているだけでなく) RAM はすべて破棄されていると想定する必要があります。FunctionWhichMayCauseCrash実際に行う最善の方法は、手に入れることができるすべてのものをログに記録することです-カーネル関数のみに依存する方法で-プロセス全体を中止し、そのIPCと共有ハンドルをすべて閉じて、独自の光沢のある新しいプロセスを開始しますアドレス空間。

このような状況で本当にきめの細かいクラッシュ リカバリが必要な場合は、パイプで接続された一連のプロセスなどに再構築する必要があります。

于 2013-02-05T03:20:27.480 に答える