.thread (Set Register Context)
The .thread command specifies which thread will be used for the register context.
.thread [/p [/r] ] [/P] [/w] [Thread]
(Live debugging only) If this option is included and Thread is nonzero, all transition page table entries (PTEs) for the process owning this thread will be automatically translated into physical addresses before access. This may cause slowdowns, because the debugger will have to look up the physical addresses for all the memory used by this process, and a significant amount of data may need to be transferred across the debug cable. (This behavior is the same as that of .cache forcedecodeuser.)
If the /p option is included and Thread is zero or omitted, this translation will be disabled. (This behavior is the same as that of .cache noforcedecodeuser.)
(Live debugging only) If the /r option is included along with the /p option, user-mode symbols for the process owning this thread will be reloaded after the process and register contexts have been set. (This behavior is the same as that of .reload /user.)
(Live debugging only) If this option is included and Thread is nonzero, all transition page table entries (PTEs) will be automatically translated into physical addresses before access. Unlike the /p option, this translates the PTEs for all user-mode and kernel-mode processes, not only the process owning this thread. This may cause slowdowns, because the debugger will have to look up the physical addresses for all memory in use, and a huge amount of data may need to be transferred across the debug cable. (This behavior is the same as that of .cache forcedecodeptes.)
(64-bit kernel debugging only) Changes the active context for the thread to the WOW64 32-bit context. The thread specified must be running in a process that has a WOW64 state.
The address of the thread. If this is omitted or zero, the thread context is reset to the current thread.
kernel mode only
live, crash dump
For more information about the register context and other context settings, see Changing Contexts.
Generally, when you are doing kernel debugging, the only visible registers are the ones associated with the current thread.
The .thread command instructs the kernel debugger to use the specified thread as the register context. After this command is executed, the debugger will have access to the most important registers and the stack trace for this thread. This register context persists until you allow the target to execute or use another register context command (.thread, .cxr, or .trap). See Register Context for full details.
The /w option can only be used in 64-bit kernel debugging sessions on a thread running in a process that has a WOW64 state. The context retrieved will be the last context remembered by WOW64; this is usually the last user-mode code executed by Thread. This option can only be used if the target is in native machine mode. For example, if the target is running on a 64-bit machine that is emulating an x86-based processor using WOW64, this option cannot be used. Using the /w option will cause the machine mode to switch automatically to an x86-based processor.
Here is an example. Use the !process extension to find the address of the desired thread. (In this case, !process 0 0 is used to list all processes, then !process is used a second time to list all the threads for the desired process.)
kd> !process 0 0 **** NT ACTIVE PROCESS DUMP **** PROCESS fe5039e0 SessionId: 0 Cid: 0008 Peb: 00000000 ParentCid: 0000 DirBase: 00030000 ObjectTable: fe529a88 TableSize: 145. Image: System ..... PROCESS ffaa5280 SessionId: 0 Cid: 0120 Peb: 7ffdf000 ParentCid: 01e0 DirBase: 03b70000 ObjectTable: ffaa4e48 TableSize: 23. Image: winmine.exe kd> !process ffaa5280 PROCESS ffaa5280 SessionId: 0 Cid: 0120 Peb: 7ffdf000 ParentCid: 01e0 DirBase: 03b70000 ObjectTable: ffaa4e48 TableSize: 23. Image: winmine.exe VadRoot ffaf6e48 Clone 0 Private 50. Modified 0. Locked 0. DeviceMap fe502e88 Token e1b55d70 ..... THREAD ffaa43a0 Cid 120.3a4 Teb: 7ffde000 Win32Thread: e1b4fea8 WAIT: (WrUserRequest) UserMode Non-Alertable ffadc6a0 SynchronizationEvent Not impersonating Owning Process ffaa5280 WaitTime (seconds) 24323 Context Switch Count 494 LargeStack .....
Now use the .thread command with the address of the desired thread. This sets the register context and enables you to examine the important registers and the call stack for this thread.
kd> .thread ffaa43a0 Using context of thread ffaa43a0 kd> r Last set context: eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=00000000 eip=80403a0d esp=fd581c2c ebp=fd581c60 iopl=0 nv up di pl nz na pe nc cs=0000 ss=0000 ds=0000 es=0000 fs=0000 gs=0000 efl=00000000 0000:3a0d ?? ??? kd> k *** Stack trace for last set context - .thread resets it ChildEBP RetAddr fd581c38 8042d61c ntoskrnl!KiSwapThread+0xc5 00001c60 00000000 ntoskrnl!KeWaitForSingleObject+0x1a1