我有一个包含73个线程的用户模式转储。其中一些是管理的,其中一些是原生的。 我想找到托管线程,哪个调用栈包含一个托管函数。
我在调试器中加载了 SOSEX 扩展名。
现在我执行~*e !mk
转储所有托管线程,然后手动浏览它们,寻找我需要的东西 - 太长而且无聊。
有更好的方法吗?
答案 0 :(得分:5)
有!findstack <module> 2
来查找堆栈上有特定模块的线程,但是恕我直言它只适用于本机调用堆栈和模块,而不适用于方法。
然后有!uniqstack
可能有助于缩小线程,以防许多线程具有相同的callstack。它也是一个本地命令。
在这种情况下我做的是一个丑陋的解决方法,但我还没有找到更好的东西:
.shell -ci "!clrstack" find "Class.Method("
当然,您可以将其与~*e
结合使用,为所有线程执行此操作。
~*e ? $tid;.shell -ci "!clrstack" find "Program.Main("
如果您不介意安装其他WinDbg扩展程序,我建议使用PyKd以获得更方便,更安静的解决方案。在WinDbg目录中创建文件findstack.py
(或者可能是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"