Debugging Tools for Windows |
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.
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.
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.
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.
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.
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.