8

どのスレッドが windbg のイベント ハンドルの所有者であるかを調べるにはどうすればよいですか。

私は走っています

!handle 00003aec f

そして得る

Handle 00003aec
  Type          Event
  Attributes    0
  GrantedAccess 0x1f0003:
     Delete,ReadControl,WriteDac,WriteOwner,Synch
     QueryState,ModifyState
  HandleCount   2
  PointerCount  4
  Name          <none>
  No object specific information available

名前がないので、スレッドが待機しているスレッドを証明するために所有者を取得する方法がわかりません

[編集] 元のプロセスをユーザーのマシンで再起動する必要があるため、ダンプに対して作業する必要があるため、ライブ セッションをデバッグできません

私がこれまでに見つけた主題に関する最良の議論はこのブログにありますが、残念ながら私たちは異なるロック方法を使用することになり (私は WaitForMultipleObjectsEx を使用し、説明は WaitForSingleObject に関するものです)、彼はライブプロセスにアクセスできるようです

私のスレッドのスタックトレース(何かでブロックされていて、現在の所有者を探している場所)は次のとおりです。

0:045> k9
ChildEBP RetAddr 
1130e050 7c90e9ab ntdll!KiFastSystemCallRet
1130e054 7c8094e2 ntdll!ZwWaitForMultipleObjects+0xc
1130e0f0 79ed98fd kernel32!WaitForMultipleObjectsEx+0x12c
1130e158 79ed9889 mscorwks!WaitForMultipleObjectsEx_SO_TOLERANT+0x6f
1130e178 79ed9808 mscorwks!Thread::DoAppropriateAptStateWait+0x3c
1130e1fc 79ed96c4 mscorwks!Thread::DoAppropriateWaitWorker+0x13c
1130e24c 79ed9a62 mscorwks!Thread::DoAppropriateWait+0x40
1130e2a8 79e78944 mscorwks!CLREvent::WaitEx+0xf7
1130e2bc 7a162d84 mscorwks!CLREvent::Wait+0x17
1130e33c 7a02fd94 mscorwks!CRWLock::RWWaitForSingleObject+0x6d
1130e364 79ebd3af mscorwks!CRWLock::StaticAcquireWriterLock+0x12e
1130e410 00f24557 mscorwks!CRWLock::StaticAcquireWriterLockPublic+0xc9
4

4 に答える 4

2

コールスタックを見ると、問題のスタックが ReaderWriterLock ロック メカニズムを使用しているように見えます。

1130e410 00f24557 mscorwks!CRWLock::StaticAcquireWriterLockPublic+0xc9

スレッド 9 に変更し、sos.dll を使用して! dsoを実行し、マネージド ReaderWriterLock オブジェクトをダンプします。次に、その ReaderWriterLock オブジェクトに対して !do を実行します。クエリできる所有スレッド フィールドがあると思います。テストして見てみます。

これを判断する昔ながらの方法は、~*e !clrstackを実行し、リーダーライター ロックを待機しているすべてのマネージド スレッドを調べてから、同じ関数に入ったがロックを通過したスレッドを見つけることができるかどうかを確認することです (つまり、異なるオフセット)

ありがとう、アーロン

注: 投稿をリンクする方法があるかどうかはわかりませんが、これは「windbg で ReaderWriterLock のロックホルダー (リーダー) を見つける方法」と非常によく似ています。

于 2009-02-22T00:23:35.350 に答える
1

コマンドを使用して!htrace、スレッド ID を取得します。最初に、おそらくプログラムの開始時に、 でトレースの収集を有効にする必要があり!htrace -enableます。

0:001> !htrace 00003aec
--------------------------------------
ハンドル = 0x00003aec - OPEN
スレッド ID = 0x00000b48、プロセス ID = 0x000011e8

...

上記の出力は架空のものであり、システムによって異なります。しかし、必要な情報 - スレッド ID (私の例では 0x00000b48) が得られます。

元のプロセスをユーザーのマシンで再起動する必要があるため、ダンプに対して作業する必要があるため、ライブ セッションをデバッグできません。

100%確実ではありませんが、これでうまくいくと思います:

  1. プロセスにアタッチして実行する!htrace -enable
  2. でプロセスから切り離しますqd。実行可能ファイルは続行されます。
  3. これで、ダンプ ファイルを取得して上記のコマンドを使用できます。説明した結果が得られると思います。
于 2009-08-19T16:24:38.973 に答える
0

カーネルダンプから掘り出すことができます。

現在、カーネルのデバッグに関する限り、sysinternals の livekd で十分ですが、残念ながら実行中のシステムでしか使用できません。

また、カーネル モードのメモリ取得ツールもあり、後で検査するために (windbg の代わりに) ダンプを取得するのに役立つ可能性があります。

それ以外の場合は、ハンドル トレースを有効にし (!htrace -enable)、(特定のスレッドに固有のコードの場合)、スタック トレースからハンドルの所有権を判断できます。

于 2009-01-22T17:43:48.207 に答える
0

これが私が見つけた決定的な答えです。自分で試したことはありません。ただし、所有者を特定するには、ライブ デバッグが必要です。しかし、それはかなり速いです。 http://weblogs.thinktecture.com/ingo/2006/08/who-is-blocking-that-mutex---fun-with-windbg-cdb-and-kd.html

于 2010-11-23T11:34:19.533 に答える