When debugging, most of the time, you have to see all stacks for all threads or to set the context for a specific thread in order to analyze it.
To do that you use the ~ command.
According to the WinDbg documentation we have:
The current thread
The thread that caused the current exception or debug event
All threads in the process
The thread whose ordinal is Number
The thread whose thread ID is TID (The brackets are required, and you cannot add a space between the second tilde and the opening bracket.)
This command is very easy to use, but it has some nuances. Otherwise, I wouldn’t be writing about it. ;-)
Let me show you the basic usage first and then a more advanced usage.
The s after the thread number, below, forces the debugger to change the thread context. In other words, all k* commands are going to operate on the new thread.
Now, things are going to be more interesting. I’m going to execute commands for each thread.
~* kvn 1000
~* e !gle
Did you notice the e? J
The e is necessary when you need to execute a debugger extension or commands that start with a dot (.)
Tip: The last command above is just to demonstrate the e usage. It’s way better and simpler to use this approach:
Look what happens if you don’t use e when you need to:
~* .echo Displaying a message.
This works fine:
~* e .echo Displaying a message.
; is used to aggregate commands, so you can do this:
~* e .echo Thread ID:; r @$tid; .echo =================
$tid gives you the thread ID. In another article I’ll discuss registers and pseudo-registers.
Here you can see scripts that use the ~ command.