I have a user mode dump with 73 threads. Some of them are managed and some of them native. I would like to find the managed thread, which call stack contains a certain managed function.
I have the SOSEX extension loaded in the debugger.
Right now I do ~*e !mk
to dump all the managed threads and then browse through them manually looking for what I need - too long and tiresome.
Is there a better way?
There is !findstack <module> 2
to find threads that have a specific module on the stack, but IMHO it only works well for native callstacks and for modules only, not for methods.
Then there is !uniqstack
which might help narrowing down the threads in case many threads have the same callstack. It's also a native command.
What I do in such cases is an ugly workaround, but I have not found something better yet:
.shell -ci "!clrstack" find "Class.Method("
Of course you can combine this with ~*e
to do it for all threads.
~*e ? $tid;.shell -ci "!clrstack" find "Program.Main("
If you don't mind installing another WinDbg extension, I recommend PyKd for a more convenient and silent solution. Create a file findstack.py
in WinDbg directory (or maybe the working directory of WinDbg, not so sure, otherwise use the full path) with the content
from pykd import *
if "Class.Method(" in dbgCommand("!clrstack"):
print(hex(expr("$tid")))
In WinDbg, run the script like this:
.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
Of course you can parameterize the script, e.g. like
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]))
and then call it with arguments
~*e !py find.py "!clrstack" "Program.Main(" "? $tid"