Controlling Threads and Processes

For an overview of threads and processes in the debugger engine, see Threads and Processes.

When an event occurs, the event thread and event process are set to the thread and process (operating system or virtual) in which the event occurred. They can be found using GetEventThread and GetEventProcess, respectively.

Implicit Threads and Processes

In kernel-mode debugging the debugger engine will use the implicit process to determine which virtual address space to use when performing virtual to physical address translation -- for example, in the methods VirtualToPhysical and ReadVirtual. When an event occurs, the implicit process is set to the current process.

The implicit process may be changed by using SetImplicitProcessDataOffset. To determine the implicit process use GetImplicitProcessDataOffset.

Note   When setting breakpoints during a live kernel debugging session, the debugger engine will pass the virtual address of the breakpoint to the target, and the target will set the breakpoint. In this case, only the process context of the target is used when handling the breakpoint; the value of the implicit process is irrelevant.

In kernel-mode debugging, the debugger engine will use the implicit thread to determine some of the target's registers. This includes the processor stack (see GetStackOffset), the frame offset (see GetFrameOffset), and the instruction offset (see GetInstructionOffset). When an event occurs, the implicit thread is set to the current thread.

The implicit thread may be changed by using SetImplicitThreadDataOffset. To determine the implicit thread, use GetImplicitThreadDataOffset.

Not all registers are determined by the implicit thread. Some registers will remain the same when the implicit thread is changed.

Warning   The implicit process and implicit thread are independent. If the implicit thread does not belong to the implicit process, then user and session state for the implicit thread will be in the wrong virtual address space and attempts to access this information will cause errors or provide incorrect results. This problem does not occur when accessing kernel memory, since kernel memory addresses are constant across all virtual address spaces. Thus information for the implicit thread located in kernel memory may be accessed independent of the implicit process.

Threads

The engine thread ID is used by the debugger engine to identify each operating system thread and each virtual thread for a target.

While a target is stopped, each thread also has an index relative to the process to which it belongs. For any process, the index of the first thread in the process is zero, and the index of the last thread is the number of threads in the process minus one. The number of threads in the current process can be found by using GetNumberThreads. The total number of threads in all processes in the current target can be found by using GetTotalNumberThreads.

The engine thread ID and system thread ID for one or more threads in the current process can be found from their index by using GetThreadIdsByIndex.

The engine maintains several pieces of information about each thread. This information may be queried for the current thread, and may be used to find the engine thread ID for a thread.

system thread ID (user-mode debugging only)
The system thread ID of the current thread can be found by using GetCurrentThreadSystemId. For a given system thread ID, the corresponding engine thread ID may be found by using GetThreadIdBySystemId.

thread environment block (TEB)
The address of the TEB for the current thread can be found by using GetCurrentThreadTeb. For a given TEB address, the corresponding engine thread ID may be found by using GetThreadIdByTeb. In kernel-mode debugging, the TEB of a (virtual) thread is the TEB of the system thread that was running on the corresponding processor when the last event occurred.

data offset
In user-mode debugging, the data offset of a (system) thread is the location of the TEB for that thread. In kernel-mode debugging the data offset of a (virtual) thread is the KTHREAD structure for the system thread that was running on the corresponding processor when the last event occurred. The data offset of the current thread can be found by using GetCurrentThreadDataOffset. For a given data offset, the corresponding engine thread ID may be found by using GetThreadIdByDataOffset.

system handle
The system handle of the current thread can be found by using GetCurrentThreadHandle. For a given system handle, the corresponding engine thread ID may be found by using GetThreadIdByHandle. In kernel-mode debugging, an artificial handle is created for each (virtual) process. This handle can only be used with debugger engine API queries.

Processes

The engine process ID is used by the debugger engine to identify each operating system process and each virtual process for a target.

While a target is stopped, each process has an index relative to the target. The index of the first process in the target is zero, and the index of the last process is the number of processes in the target minus one. The number of processes in the current target can be found by using GetNumberProcesses.

The engine process ID and system process ID for one or more threads in the current target can be found from their index by using GetProcessIdsByIndex.

The engine maintains several pieces of information about each process. This information may be queried for the current process, and may be used to find the engine process ID for a process.

system process ID (user-mode debugging only)
The system process ID of the current process can be found by using GetCurrentProcessSystemId. For a given system process ID, the corresponding engine process ID may be found by using GetProcessIdBySystemId.

process environment block (PEB)
The address of the PEB for the current process can be found by using GetCurrentProcessPeb. For a given PEB address, the corresponding engine process ID may be found by using GetProcessIdByPeb. In kernel-mode debugging, the PEB of the (virtual) process is the PEB of the system process that was running when the last event occurred.

data offset
In user-mode debugging, the data offset of a (system) process is the location of the PEB of that process. In kernel-mode debugging, the data offset of the (virtual) process is the KPROCESS structure for the system process that was running when the last event occurred. The data offset of the current process can be found by using GetCurrentProcessDataOffset. For a given data offset, the corresponding engine process ID may be found by using GetProcessIdByDataOffset.

system handle
The system handle of the current process can be found by using GetCurrentProcessHandle. For a given system handle, the corresponding engine process ID may be found by using GetProcessIdByHandle. In kernel-mode debugging, an artificial handle is created for the (virtual) process. This handle can only be used with debugger engine queries.

Events

In live user-mode debugging, whenever a thread is created or exits in a target, the create-thread and exit-thread debugging events are generated. These events result in calls to the IDebugEventCallbacks::CreateThread and IDebugEventCallbacks::ExitThread callback methods.

In live user-mode debugging, whenever a process is created or exits in a target, the create-process and exit-process debugging events are generated. These events result in calls to the IDebugEventCallbacks::CreateProcess and IDebugEventCallbacks::ExitProcess callback methods.

For more information about events, see Monitoring Events.

Additional Information

For more information about threads and processes, including the TEB, KTHREAD, PEB, and KPROCESS structures, see Microsoft Windows Internals by David Solomon and Mark Russinovich.