Получить потоки, которые содержат определенную функцию.NET в своем стеке вызовов?
У меня дамп пользовательского режима с 73 потоками. Некоторые из них являются управляемыми, а некоторые - родными. Я хотел бы найти управляемый поток, стек вызовов которого содержит определенную управляемую функцию.
У меня есть расширение SOSEX, загруженное в отладчик.
Щас делаю ~*e !mk
сбросить все управляемые потоки, а затем просмотреть их вручную в поисках того, что мне нужно - слишком долго и утомительно.
Есть ли способ лучше?
1 ответ
Связанные команды
Есть !findstack <module> 2
чтобы найти потоки, которые имеют определенный модуль в стеке, но IMHO, он работает только для собственных вызовов и только для модулей, но не для методов.
Тогда есть !uniqstack
что может помочь сузить потоки в случае, если у многих потоков есть один и тот же стек вызовов. Это также родная команда.
Гадкое встроенное решение
То, что я делаю в таких случаях, - уродливый обходной путь, но я еще не нашел что-то лучшее:
.shell -ci "!clrstack" find "Class.Method("
Конечно, вы можете объединить это с ~*e
сделать это для всех потоков.
~*e ? $tid;.shell -ci "!clrstack" find "Program.Main("
Скрипт PyKd
Если вы не против установить другое расширение WinDbg, я рекомендую PyKd для более удобного и тихого решения. Создать файл findstack.py
в каталоге WinDbg (или, возможно, в рабочем каталоге WinDbg, не уверен, в противном случае используйте полный путь) с содержимым
from pykd import *
if "Class.Method(" in dbgCommand("!clrstack"):
print(hex(expr("$tid")))
В WinDbg запустите скрипт так:
.load E:\path to\x86\pykd.pyd
*** Actually it's a DLL and I prefer renaming it
*** .load E:\path to\x86\pykd.dll
~*e !py findstack.py
Конечно, вы можете параметризовать скрипт, например, как
from pykd import *
import sys
if (len(sys.argv) < 4):
print "find <command> <search term> <success command>."
quit()
if sys.argv[2] in dbgCommand(sys.argv[1]):
print(dbgCommand(sys.argv[3]))
а затем вызвать его с аргументами
~*e !py find.py "!clrstack" "Program.Main(" "? $tid"