- name
- kernel-debug
- description
- Kernel-debug a Windows test VM over kdnet with kd.exe running on its debugger dev VM — attach, watch the display miniport's DbgPrint output live while it loads, break in to a hung guest, collect bugcheck analysis, resume, and find user-mode DLL load failures with loader snaps. Use when a driver will not load, the guest hangs or bugchecks, a frozen VM may be halted in the debugger, or someone asks to "attach kd", "break in", "get the bugcheck" or "watch the KMD log".
- argument-hint
- [start|break|crash|send <cmd>|stop]
# Kernel debugging over kdnet
Request: `$ARGUMENTS`
`UB="python3 ${CLAUDE_PLUGIN_ROOT}/scripts/utmbot"`
## Before running
- The test VM was made by `/utmapp-bot:provision-windows-test-vm`. Its
state records the debugger dev VM and the kdnet port; `kdtest` proved the
link.
- The debugger dev VM is running, and the host reaches it over SSH.
- kd runs **on the dev VM**. It debugs the test VM over the host-only kdnet
network (`192.168.240.0/24`, key `1.1.1.1`).
## Run
```sh
$UB kd start # attach; kernel DbgPrint now streams to kd.log
$UB kd tail 60 # read it (works while the target runs)
$UB kd status # attached? target halted at a prompt?
$UB kd break # halt the target (restarts kd with -b); freezes the VM
$UB kd send "!process 0 0 dwm.exe" # only while halted
$UB kd crash # .lastevent, .bugcheck, !analyze -v, kv, lmv viogpu3d
$UB kd go # resume
$UB kd stop # detach (also before rebuilding the KMD: kd locks its PDB)
```
`kd.log` lives in `~/.utmapp-bot/runs/<vm>/kd/`. Start kd **before** the
thing you want to watch, e.g. before `$UB install`, so the miniport's
`DriverEntry`/`StartDevice` messages are captured.
## What it does
- kd reads commands from a local FIFO that a detached holder process keeps
open, so kd never sees end-of-input between commands. Its output appends to
kd.log.
- `send` refuses unless the last line of kd.log is a `kd>` prompt. Over
kdnet a running target cannot be interrupted through a pipe, so commands
only run while it is halted. `break` restarts kd with `-b`, which breaks in
at the next kdnet connection. That halts a running or hung target.
- A halted target **freezes every vCPU**: SSH, the display and the guest
clock all stop until `go`. Do not leave it halted.
- Symbols: `--sympath` takes a symbol path on the dev VM. The default is
`C:\utmbot\symbols`; put the driver's PDBs there or point at the build
output. The Microsoft symbol server (`srv*…*https://msdl.microsoft.com/download/symbols`)
resolves `nt`/`dxgkrnl` but makes commands slow.
## Patterns
- **"The VM froze."** Check `$UB kd status` before anything else. A halted
target looks exactly like a hang: window frozen, SSH dead, debug.log
stopped at the same second. Typical causes:
- a Code Integrity break (`… not signed correctly`, harmless with test
signing; `kd go`);
- an assertion (`c0000420`) or `int3` (`80000003`);
- a bugcheck.
The test VMs are provisioned with `/noumex`, so user-mode exceptions do not
break in. A game whose anti-tamper still misbehaves under a debugger runs
with `$UB vm up --nodebug`.
- **Bugchecks halt instead of rebooting** while kd is attached. Collect with
`kd crash` before anything else. A manual `.crash` from kd *reboots* a
kdnet target instead of holding it, so catch natural bugchecks. TDR
recovery cannot be tested with kd attached: dxgkrnl bugchecks with `0x116`.
- **Driver load, live.** `kd start`, then `$UB install`. The KMD's messages
show where `StartDevice` fails. If the KMD prints nothing, its debug
verbosity registry value was not set before the install.
- **A user-mode DLL that fails to load.** Enable loader snaps for that exe
(IFEO `GlobalFlag=2`, see the triage skill's install-and-load.md). The
loader then prints the exact missing DLL and status to kd.
- **Hang analysis while halted:**
- `!process 0 7 <image>` gives every thread's kernel stack;
- `!locks` for a deadlock (`Possible deadlock` in kd.log);
- `!running -it` for what the CPUs are doing;
- `lmv m viogpu3d` confirms the loaded driver build.
## When it fails
- **`kd start`: debugger VM not reachable**: start it in UTM; it must be
the VM named in the test VM's provision state.
- **`break` never halts**: kdnet is not connecting. Check:
- the test VM is booted with debugging on (`bcdedit /enum` shows
`debug Yes`);
- its kdnet adapter (KDNIC) is up;
- no other kd holds the port (`kd stop` kills every kd.exe on the dev VM).
`provision-windows-test-vm --only kdtest` re-checks the link.
- **Nothing streams but the target runs**: a previous kd still owns the
port, or the target was booted with `--nodebug` (kernel debugging off for
that boot).
Voir sur GitHub