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:

 

Thread identifier

Description

~.

The current thread

~#

The thread that caused the current exception or debug event

~*

All threads in the process

~Number

The thread whose ordinal is Number

~~[TID]

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.

 

~.

 

 

 

~#

 

 

 

~*

 

 

 

~<Number>s

 

 

 

~~[TID]s

 

 

 

 

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:

 

!gle -all

 

 

 

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.