CPU¶
- !apic¶
Show a processor’s local APIC: its ID, priorities, LVT, timer, and pending vectors.
!apic [processor]
Also:
apicReads the local APIC of the selected processor, or of the processor you give: in x2APIC mode through its MSRs (0x800-0x83f), in xAPIC mode through its registers at the physical address IA32_APIC_BASE names, read uncached. Both need a backend that reads MSRs and device registers: kd or kdnet. The target reads them on the processor that stopped it, so for another processor ntoseye switches the target to it and back, as rdmsr /p does. Shows the APIC ID and version, whether it is the bootstrap processor, the task and processor priorities, the spurious-interrupt vector register, the logical destination, the interrupt command register as an IPI (vector, delivery mode, destination), each local vector table entry (timer, LINT0, LINT1, error, performance counter, thermal, CMCI) with its vector, delivery mode, trigger, and mask, the timer’s counts and divisor, the error status, and the vectors in service (ISR), requested (IRR), and level-triggered (TMR).
- !cpuinfo¶
Show processor identification, speed, and feature bits.
!cpuinfo
Also:
cpuinfoShows the processor number, vendor, family, model, stepping, speed, and feature bits if they are available. For a field that is not available, ntoseye uses the triage-dump metadata.
- !dpcs¶
List the deferred procedure calls that are queued on each processor.
!dpcs
Also:
dpcsThe command walks the two _KPRCB DpcData queues. Each walk detects cycles and has an entry limit.
- !exqueue¶
Show the executive worker queues with their pending work items and worker threads.
!exqueue [flags]
Also:
exqueueWindows 10 and later keep one _EX_WORK_QUEUE for each partition, NUMA node, and queue index (_EXQUEUEINDEX: ExPoolUntrusted, IoPoolUntrusted, …). The command finds the queues from the ExPartition of each _EPARTITION. For each queue, it shows the thread count and limits, the concurrency (_KPRIQUEUE.MaximumCount), and the number of work items processed. Then it shows each pending _WORK_QUEUE_ITEM by priority, with its routine as a symbol and, for an IoQueueWorkItem item, the I/O routine, object, and context. After the items come the threads that serve the queue, with their state and wait reason. Each priority shows the WORK_QUEUE_TYPEs that map to it, and its running threads against the concurrency. The command reads these priorities from nt!ExpBuiltinPriorities (CriticalWorkQueue is 13, DelayedWorkQueue is 12, HyperCriticalWorkQueue is 15). The flags are the same as in WinDbg. 0x4 adds the stack of each worker thread (32 frames). 0x10, 0x20, and 0x40 show only the items of the critical, delayed, and hypercritical priorities. The command accepts 0x1 and 0x2, but it always lists the threads. Each list walk detects cycles and has an entry limit: 1,024 items for each priority and 4,096 threads for each queue.
- !gdt¶
Decode the bounded GDT of the current processor.
!gdt
Also:
gdtShows the bounded GDT entries of the selected processor, with the base, limit, privilege, mode, and presence of each entry.
- !idt¶
Decode one IDT entry or the bounded 256-entry IDT.
!idt [vector]
Also:
idtShows one IDT vector or all 256 entries, with the handler, selector, gate type, DPL, presence, and non-nt hooks of each entry. Under a vector that dispatches through KiIsrThunk, the KINTERRUPT the processor has connected to it and its service routine.
- !ioapic¶
Show the I/O APIC and PIC lines as the HAL set them up.
!ioapic
Also:
ioapicWalks the HAL’s registered interrupt controllers (nt!HalpRegisteredInterruptControllers) and shows each one, an I/O APIC or a legacy PIC, with its unit ID, ACPI resource ID, line range, and any problem the HAL recorded, then each line the HAL set up, from its own record of the line (_INTERRUPT_LINE_STATE): the line and its global system interrupt, the vector, the IRQL, edge or level trigger, polarity, and the processor target. This is what the HAL programmed into the redirection entries, read from kernel memory, so it works on every backend and in a kernel dump; it does not read the I/O APIC’s registers.
- !ipi¶
Show the interprocessor interrupt (IPI) state of one processor or of all processors.
!ipi [processor]
Also:
ipiFor each processor, shows the IPI fields that its _KPRCB has on this Windows build. IpiFrozen is the freeze state that the debugger and KeFreezeExecution control (Running, Frozen, Freeze owner, …). TargetCount and PacketBarrier apply to the processor as a sender and show the targets that did not finish its packet yet. The command also shows SelfIpiRequestSummary and IpiFrame, the trap frame of the IPI that the processor services now. Windows 10 and later builds have one mailbox for each sender, and on these builds the command also shows the requests that are in the queue of the processor and are not taken yet. For each request, it shows the sender, the request type, and for a packet, the worker routine and parameters. The request type (packet, TB flush, or cache flush) comes from RequestSummary. For the processor as a sender, the command also shows the processors whose queues still hold its request.
- !irql¶
Show the current IRQL of a processor.
!irql [processor]
Also:
irqlShows the current IRQL and the Windows level name of the selected processor. At a KD break-in, this is the IRQL that the debugger sees, which can be different from the level before the break-in.
- !pcr¶
Show the main KPCR data of the selected processor.
!pcr [processor]
Also:
pcrShows the KPCR and KPRCB addresses, the thread pointers, the descriptor registers, the TSS, and the available IRQL fields. On AMD64 Windows, kernel GS usually points to the KPCR, and backend GS-base registers are optional.
- !prcb¶
Show the main KPRCB data of the selected processor.
!prcb [processor]
Also:
prcbShows the processor number, the thread pointers, the DPC and interrupt counters, and the available ProcessorState metadata of the selected KPRCB.
- !qlocks¶
Show which processors own or wait for each numbered queued spinlock.
!qlocks
Also:
qlocksReads the _KPRCB.LockQueue entries of each processor, which hold one _KSPIN_LOCK_QUEUE for each _KSPIN_LOCK_QUEUE_NUMBER lock. The table has the same layout as in WinDbg, with one row for each lock and one column for each processor. O marks the owner, and 1-n marks the wait order, which the command finds by following the queue links from the owner. C marks an entry whose owner or wait bits do not agree with the links. The table shows only the numbered locks (KeAcquireQueuedSpinLock). In-stack queued spinlocks are on the stacks of the callers that acquire them.
- !ready¶
List the dispatcher ready queues of all processors or of one processor.
!ready [processor]
Also:
readyThe command reads DispatcherReadyListHead from each _KPRCB, or ReadyListHead on newer builds. Each queue walk has an entry limit and, like
dt -l, reports null links, cycles, unreadable links, and when it reaches its entry limit.
- !running¶
Show the thread that runs on each processor.
!running [-i] [-t]
Also:
running-i includes idle threads, and -t adds a short kernel stack, with a frame limit, for each processor.
- !sysinfo¶
Show the machine’s SMBIOS identity, its SMBIOS tables, or its processor.
!sysinfo <machineid|smbios|cpuinfo>
Also:
sysinfoReads the SMBIOS table the kernel found at boot (nt!WmipSMBiosTablePhysicalAddress) from physical memory. machineid shows the BIOS vendor, version, and date, and the system’s and baseboard’s manufacturer, product, and version, as WinDbg’s !sysinfo machineid does. smbios lists every structure in the table with its type, handle, and length, and decodes the BIOS, system, baseboard, enclosure, processor, memory array, memory device, and mapped address structures. cpuinfo shows the current processor as !cpuinfo does.
- !timer¶
List the kernel timers or decode one _KTIMER.
!timer [address]
Also:
timerWithout an address, the command walks _KPRCB.TimerTable.TimerEntries. With an address, it decodes one timer and its DPC.
- dg¶
Decode segment selectors from the GDT of the current processor.
dg <first-selector> [last-selector]
Shows each selector from the first to the last, in steps of 8 as WinDbg does. For each selector, it shows the descriptor base, limit, type, privilege level, size (Bg/Nb), granularity (Pg/By), presence (P/NP), long mode (Lo/Nl), and attribute flags. If a selector refers to an LDT (bit 2 set), dg reports this and does not decode the selector. 64-bit Windows has no LDT.
- rdmsr¶
Read a model-specific register from a halted processor.
rdmsr [/p <processor>] <msr>
Reads one model-specific register on the selected processor, or on another processor that you select with /p. The dump and memory backends show that MSR access is unavailable. On an ARM64 target the register is a system register: by name (MIDR_EL1, TTBR1_EL1, CNTVCT_EL0, …), as S
_ _C C , or by the number KD reads it by, op0<<16 | op1<<12 | CRn<<8 | CRm<<4 | op2 (MIDR_EL1 is 0x30000).
- wrmsr¶
Write a model-specific register on the current processor.
wrmsr <msr> <value>
Writes one model-specific register on the current processor. You can use a common IA32_* name instead of the numeric MSR. On an ARM64 target the register is a system register, named as rdmsr takes it.