microsoft/openvmm

Public

mirrored fromhttps://github.com/microsoft/openvmmAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
045b1b0dbef400c88d68fce3fbe84ee2cedb2fa2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

Guide/src/reference/dev_feats/gdbstub.md

171lines · modecode

1# Hardware Debugging (gdbstub)
2
3Think EXDI from Hyper-V, except instead of using the EXDI interface, we use the
4[GDB Remote Serial Protocol](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html)
5(via the [`gdbstub`](https://github.com/daniel5151/gdbstub/) Rust library).
6
7Hardware debugging has several benefits over using an in-guest / in-kernel debugger:
8
9- Debugging early-boot scenarios (before UEFI / Windows / Linux debuggers are set up)
10- Debugging low-level ISRs
11- Non-intrusive debugging = easier to repro certain bugs
12- Debugging SNP/TDX/VBS Confidential VMs
13
14## Enabling the Debugger
15
16### OpenVMM
17
181. Pass the `--gdb <port>` flag at startup to enable the
19debug worker. e.g., `--gdb 9001`
20
21To pause the VM until the debugger has been attached, pass `--paused` at startup.
22
23### OpenHCL
24
251. Pass the `OPENHCL_GDBSTUB=1` `OPENHCL_GDBSTUB_PORT=<gdbstub port>` parameters to enable gdbstub. e.g., `Set-VmFirmwareParameters -Name UhVM -CommandLine OPENHCL_GDBSTUB=1 OPENHCL_GDBSTUB_PORT=5900`.
262. To expose a TCP port, run `ohcldiag-dev.exe <name> vsock-tcp-relay --allow-remote --reconnect <gdbstub port> <tcp port>`.
27
28To pause VTL0 boot until desired, pass `OPENHCL_VTL0_STARTS_PAUSED=1` as a parameter. Then once the debugger is attached, you can start VTL0 with `ohcldiag-dev.exe <name> resume`.
29
30## Connecting via GDB
31
32The quickest way to get connected to a OpenVMM VM is via `gdb` directly.
33
34Note that GDB does _not_ support debugging PDBs, so if you're trying to debug
35Windows, you'll be limited to plain disassembly. See the [`Connecting via
36WinDbg`](#connecting-via-windbg) section below if this is your use-case.
37
38On the flipside, if you're trying to debug ELF images with DWARF debug info
39(e.g., a vmlinux binary), then you'll likely want to use `gdb` directly, as it
40will support source-level debugging with symbols, whereas WinDbg will not.
41
42You can install `gdb` via your distro's package manager. e.g., on Ubuntu:
43
44```bash
45sudo apt install gdb
46```
47
48Once `gdb` is installed, run it, and enter the following `gdb` command (swapping
49`9001` for whatever port you specified at the CLI)
50
51```text
52target remote :9001
53```
54
55If all goes well, you should get output similar to this:
56
57```text
58(gdb) target remote :9001
59Remote debugging using :9001
60warning: No executable has been specified and target does not support
61determining executable automatically. Try using the "file" command.
620xfffff8015c054c1f in ?? ()
63(gdb)
64```
65
66At this point, you can try some basic GDB commands to make sure things are working.
67
68e.g., start / interrupt the VM's execution using `cont` and `ctrl-c`
69
70```text
71(gdb) cont
72Continuing.
73^C # <-- hit ctrl-c in the terminal
74Thread 1 received signal SIGINT, Interrupt.
750xfffff8015c054c1f in ?? ()
76(gdb)
77```
78
79e.g., inspecting register state
80
81```text
82(gdb) info registers
83rax 0x0 0
84rbx 0x0 0
85rcx 0x40086 262278
86rdx 0x0 0
87rsi 0xffff960d4eea5010 -116491073990640
88rdi 0x0 0
89rbp 0x0 0x0
90rsp 0xfffff8015b3f5ec8 0xfffff8015b3f5ec8
91r8 0x0 0
92r9 0xffffffff 4294967295
93r10 0xfffff8015bfff1f0 -8790254554640
94r11 0x0 0
95r12 0xffffffff 4294967295
96...etc...
97```
98
99e.g., setting data breakpoints
100
101```text
102(gdb) awatch *0xfffff804683190e0
103Hardware access (read/write) watchpoint 1: *0xfffff804683190e0
104```
105
106e.g., single stepping
107
108```text
1090xfffff8047a309686 in ?? ()
110(gdb) si
1110xfffff8047a309689 in ?? ()
112```
113
114You may find [this blog post](https://blog.mattjustice.com/2018/08/24/gdb-for-windbg-users/)
115useful, as it includes a table of common `gdb` commands along with their WinDbg
116counterparts.
117
118## Connecting via WinDbg
119
120WinDbg doesn't understand the GDB Remote Serial Protocol directly, but
121thankfully, some smart folks over on the WinDbg team have developed a GDB Remote
122Serial Protocol <-> WinDbg translation layer!
123
124For more information, see
125[Setting Up QEMU Kernel-Mode Debugging using EXDI](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/setting-up-qemu-kernel-mode-debugging-using-exdi)
126
127Getting this working with OpenVMM or OpenHCL is as easy as following the guide,
128except you'll need to [enable our debugger](#enabling-the-debugger) instead of
129running QEMU.
130
131It's easiest to connect through the GUI. The steps are relatively simple: Open Windbgx -> File -> Attach to kernel -> EXDI. On the form, fill out:
132
133- Target Type: `QEMU`
134- Target Architecture: `X64`
135- Target OS: `Windows`
136- Image Screening heuristic size: `0xFFFE - NT`
137- Gdb server and port: `<server>:<port>` e.g., `127.0.0.1:1337` (use whatever port you set above)
138
139### Known WinDbg Bugs
140
141- Hardware breakpoints are issued with [`ba`](https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggercmds/ba--break-on-access-). The `Access Size` parameter is incorrectly multiplied by 8 when sent to the stub. Consequently, it _must_ be set to 1.
142- Unlike GDB, WinDbg doesn't implicitly set software breakpoints via our offered write_addrs implementation.
143
144---
145
146## Supported Features
147
148At the time of writing (8/16/24) the debugger supports the following operations:
149
150- read/write guest memory
151- read guest registers \*
152- start/interrupt execution
153- watchpoints
154- hardware breakpoints
155- single stepping
156
157## TODO Features
158
159If you're looking for work, and want to improve the debugging experience for
160everyone, consider implementing one or more of the following features:
161
162- \* reading _all_ guest registers, including fpu, xmm, and various key msrs
163- software breakpoints:
164 - Intercept guest breakpoint exceptions into VTL2
165- writing guest registers
166- exposing the OpenVMM interactive console via the
167 [`MonitorCmd`](https://docs.rs/gdbstub/latest/gdbstub/target/ext/monitor_cmd/trait.MonitorCmd.html)
168 interface
169 - Custom commands sent using `monitor` (gdb) / `.exdicmd` (WinDbg)
170 - e.g., being able to invoke `x device/to/inspect` directly from the debugger
171- [any other features supported by the `gdbstub` library](https://github.com/daniel5151/gdbstub#debugging-features)