Как мне найти владельца ручки из зависшей свалки с помощью windbg? - PullRequest
8 голосов
/ 22 января 2009

Как узнать, какой поток является владельцем моего дескриптора события в 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

назад, и поскольку имени нет, я не понял, как вывести владельца, чтобы доказать, какую нить ожидает моя нить

[Edit] Я должен работать против дампа, так как исходный процесс должен быть перезапущен на компьютере пользователя, поэтому я не могу отладить живой сеанс

Лучшее обсуждение на эту тему, которое я нашел до сих пор, - в этом блоге , но, к сожалению, мы используем разные методы блокировки (я использую 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 ]

2 голосов
/ 22 февраля 2009

Глядя на стек вызовов, выясняется, что рассматриваемый стек использует механизм блокировки ReaderWriterLock.

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

Перейдите в поток 9 и, используя sos.dll , запустите ! Dso , чтобы выгрузить управляемый объект ReaderWriterLock. Затем запустите! Do для этого объекта ReaderWriterLock. Я полагаю, что есть собственное поле потока, которое вы можете запросить. Я проверю это и посмотрю.

Старый способ определить это - запустить ~ * e! Clrstack , проверить все управляемые потоки, ожидающие блокировки чтения-записи, и посмотреть, сможете ли вы найти поток, который вошел в ту же функцию но прошел через замок (т.е. другое смещение)

Спасибо, Аарон

Примечание: не уверен, есть ли способ связать сообщения, но этот очень похож на
Как найти держатель замка (читатель) моего ReaderWriterLock в windbg

1 голос
/ 19 августа 2009

Используйте команду !htrace, чтобы получить идентификатор потока. Сначала вы должны, возможно в начале программы, включить сбор трасс с помощью !htrace -enable.

0:001> !htrace <b>00003aec</b>
--------------------------------------
Handle = <b>0x00003aec</b> - OPEN
Thread ID = <i>0x00000b48</i>, Process ID = 0x000011e8

...

Приведенный выше вывод является вымышленным, он будет отличаться для вашей системы. Но он даст вам необходимую информацию - идентификатор потока (0x00000b48 в моем примере).

Я должен работать против дампа как оригинальный процесс должен быть перезапущен на компьютере пользователя, поэтому не могу отладить живая сессия.

Я не уверен на 100%, но думаю, что это сработает:

  1. Присоединиться к процессу и запустить !htrace -enable
  2. Отключиться от процесса с помощью qd. Исполняемый файл будет продолжен.
  3. Теперь вы можете взять файл дампа и использовать приведенную выше команду - я думаю, что вы получите описанные результаты.
0 голосов
/ 23 ноября 2010

Вот окончательный ответ, который я нашел. Никогда не пробовал себя. Вам понадобится отладка в реальном времени, чтобы определить владельца. Но это довольно быстро. http://weblogs.thinktecture.com/ingo/2006/08/who-is-blocking-that-mutex---fun-with-windbg-cdb-and-kd.html

0 голосов
/ 22 января 2009

Вы можете выкопать это из дампа ядра.

Теперь, что касается отладки ядра, livekd от ​​sysinternals должно быть достаточным, но, к сожалению, его можно использовать только в работающей системе.

Также имеется режим ядра инструмент сбора памяти , который может быть полезен для получения дампа с (вместо windbg) для последующей проверки.

В противном случае, включив трассировку дескриптора (! Htrace -enable) и (если код уникален для определенного потока), владение дескриптором может быть установлено из трассировки стека.

...