web-dev-qa-db-ja.com

C#アプリケーションでのデッドロックの検出

重複の可能性:
競合状態/デッドロックを見つけるためのC#/。NET分析ツール

デッドロックしてハングしていると思われるアプリケーションをデバッグしています。ただし、これは数日ごとにのみ発生し、コンピューターでは発生しないため、デバッガーを接続できません。実行中のアプリケーションにクエリを実行し、どのメソッド/ロック/デッドロックが発生しているかを確認するために使用できるユーティリティまたはメソッドはありますか?

更新:通常、アプリケーションは顧客の場所で実行されており、私はマシンにアクセスできません。大量のソフトウェアをインストールします。

23
Jon Tackabury

通常のlockMonitor.Enterアプローチを使用して一部のデータをロックする代わりに、「TimedLock」構造を使用することもできます。このTimedLockは、ロックをタイムリーに取得できなかった場合に例外をスローします。また、解放しなかったロックがある場合は警告を表示することもできます。

This IanGriffithsによる記事が役立つかもしれません。

8

WinDbg を使用して、アプリケーションのスレッドを検査できます。これがあなたができることの簡単な計画です。

  • アプリケーションがハングした場合は、WinDbgファイルをマシンにコピーします。
  • WinDbgをプロセスにアタッチするか、ADPlusを使用してプロセスのハングダンプを取得します。 ADPlusを選択した場合は、WinDbgにダンプをロードします。
  • WinDbgからsos.dllをロードして、マネージコードを検査できるようにします。
  • !threadsコマンドはアプリケーション内のすべてのスレッドを表示し、!clrstackコマンドはそれらが何をしているかを表示します。 ~e!clrstackを使用して、すべてのスレッドのコールスタックをダンプします。ロックを示しているので、Waitメソッドの呼び出しを探します。
  • !syncblkコマンドは、どのスレッドがさまざまなロックを保持しているかについての情報を提供します。
  • 特定のスレッドが取得しようとしているロックを見つけるには、スレッドに切り替えてスタックオブジェクトを調べます(!dso)。ここから、スレッドが取得しようとしているロックを見つけることができるはずです。

明確化:WinDbgは定期的なインストールを必要としません。ファイルをコピーするだけです。また、ハングダンプを取得する場合は、必要に応じて別のマシンでデバッグを続行できます。

追加: Sosex には、多くの状況でデッドロックを自動的に識別する!dlkコマンドがあります。常に機能するわけではありませんが、機能する場合はすべての機能を実行するため、これを最初に選択する必要があります。

23
Brian Rasmussen

並行プログラミングのタイムアウトは恐ろしい考えです。これは非決定論につながり、したがって再現できない動作につながります。 [〜#〜]チェス[〜#〜] のようなデッドロック検出ツールを使用してみてください。さらに良いことに、ロックフリーアルゴリズムで使用されるロックの数を最小限に抑えるか、ロックを完全に避けてプログラムをシングルスレッドコンパートメントに分割し、キューを使用してコンパートメント間でデータを渡します(メッセージパッシング/アクター同時実行として知られています)。

6
naasking

http://blogs.technet.com/askperf/archive/2007/06/15/capturing-application-crash-dumps.aspx の終わりは、Vistaでは少なくともクラッシュする可能性があることを示していますタスクマネージャーを使用して実行中のプロセスのダンプ。

1
ChrisW

あなたは実際にそこに非常に興味深い問題を抱えています。あなたができることがいくつかあります:

優れたロガーを使用する:マルチスレッドエラーを再現する方法の1つは、実行されたアクションとそれらを実行したスレッドを出力するロガーを用意することです。これにより、エラーへのガイドとなるトレースを見つけることができます。ロガーを追加できれば、これはかなり簡単な解決策です。

FSPの使用:FSPを使用してマルチスレッドシステムを定義します。このようにして、エラーを見つけるためにウォークスルーできるプロセスの有限状態マシンを作成できます。このソリューションは、より数学的なソリューションです。

私があなたに与える2つの解決策/手順は、いくつかの英国の大学とアメリカの大学の間でマルチスレッド開発に取り組むことの主な違いです。英国では、教授はプログラムする前にFSPを使用してシステムにエラーがないことを証明しようとする方が親切であり、アメリカ人は正しく機能することを証明するためにテストすることを好みます。

私は本当にこの本を読むことをお勧めします:JeffMageeとJeffKramer:Concurrency:State Models and Java Programs、Wiley、1999

1
mandel

これは非常に興味深い問題であり、数日おきにしか発生しないため、苦痛です。私は CodeProjectに関するこの記事 を見つけました。それはあなたにとっての始まりかもしれません。

昔ながらのアプローチは、大量のメッセージをログに記録し、ログファイルを使用してそれがいつ発生したかを検出しようとすることです。 :)

0
Szymon Rozga

ここでの回答に加えて、一般的なスレッドプログラミングで役立つもう1つのことは、開発ボックスがマルチプロセッサマシンであることを確認することです。特に、デッドロックは(通常)はるかに確実に再現されます。

0
Tim Jarvis