-
Notifications
You must be signed in to change notification settings - Fork 134
Add support for Hyperlight KVM guest debugging using gdb #111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
b0e8a34
add gdb cargo feature
dblnz ca9bb89
disable timeouts for messaging between host and hypervisor handler wh…
dblnz 793f66c
add guest debug port to sandbox configuration
dblnz 9d3e0b1
add gdb debug thread creation method
dblnz 3ae6d7d
add debug communication channel type
dblnz 0079d7f
add hyperlight sandbox target to handle gdb commands support
dblnz 6d1871d
handle debug vcpu exit on kvm side
dblnz 1d2bdca
add kvm debug configuration that handles vCPU interaction
dblnz 9a73d85
add read/write registers support
dblnz 5479831
hw breakpoint and resume support added
dblnz ad4b582
add stepping support
dblnz 323c6c5
add a way to read/write host shared mem when debugging
dblnz b60b808
add read/write address and text section offset support
dblnz 5ee059d
add sw breakpoint support
dblnz a0bd86d
add ci checks for the gdb feature
dblnz 6440a19
add documentation about the gdb debugging feature
dblnz b18ff56
add a way to report a non-fatal error to gdb
dblnz cfaefc3
add CI gdb test
dblnz 0a03f81
add support for interrupts
dblnz 251cdb4
move gdb thread creation in hypervisor handler
dblnz 7ab2149
improve error handling and avoid panicking
dblnz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
# How to debug a Hyperlight **KVM** guest using gdb | ||
|
||
Hyperlight supports gdb debugging of a **KVM** guest running inside a Hyperlight sandbox. | ||
When Hyperlight is compiled with the `gdb` feature enabled, a Hyperlight KVM sandbox can be configured | ||
to start listening for a gdb connection. | ||
|
||
## Supported features | ||
|
||
The Hyperlight `gdb` feature enables **KVM** guest debugging: | ||
- an entry point breakpoint is automatically set for the guest to stop | ||
- add and remove HW breakpoints (maximum 4 set breakpoints at a time) | ||
- add and remove SW breakpoints | ||
- read and write registers | ||
- read and write addresses | ||
- step/continue | ||
- get code offset from target | ||
|
||
## Expected behavior | ||
|
||
Below is a list describing some cases of expected behavior from a gdb debug | ||
session of a guest binary running inside a KVM Hyperlight sandbox. | ||
|
||
- when the `gdb` feature is enabled and a SandboxConfiguration is provided a | ||
debug port, the created sandbox will wait for a gdb client to connect on the | ||
configured port | ||
- when the gdb client attaches, the guest vCPU is expected to be stopped at the | ||
entry point | ||
- if a gdb client disconnects unexpectedly, the debug session will be closed and | ||
the guest will continue executing disregarding any prior breakpoints | ||
- if multiple sandbox instances are created, each instance will have its own | ||
gdb thread listening on the configured port | ||
- if two sandbox instances are created with the same debug port, the second | ||
instance logs an error and the gdb thread will not be created, but the sandbox | ||
will continue to run without gdb debugging | ||
|
||
## Example | ||
|
||
### Sandbox configuration | ||
|
||
The `guest-debugging` example in Hyperlight demonstrates how to configure a Hyperlight | ||
sandbox to listen for a gdb client on a specific port. | ||
|
||
### CLI Gdb configuration | ||
|
||
One can use a gdb config file to provide the symbols and desired configuration. | ||
|
||
The below contents of the `.gdbinit` file can be used to provide a basic configuration | ||
to gdb startup. | ||
|
||
```gdb | ||
# Path to symbols | ||
file path/to/symbols.elf | ||
# The port on which Hyperlight listens for a connection | ||
target remote :8080 | ||
set disassembly-flavor intel | ||
set disassemble-next-line on | ||
enable pretty-printer | ||
layout src | ||
``` | ||
One can find more information about the `.gdbinit` file at [gdbinit(5)](https://www.man7.org/linux/man-pages/man5/gdbinit.5.html). | ||
|
||
### End to end example | ||
|
||
Using the example mentioned at [Sandbox configuration](#sandbox-configuration) | ||
one can run the below commands to debug the guest binary: | ||
|
||
```bash | ||
# Terminal 1 | ||
$ cargo run --example guest-debugging --features gdb | ||
``` | ||
|
||
```bash | ||
# Terminal 2 | ||
$ cat .gdbinit | ||
file src/tests/rust_guests/bin/debug/simpleguest | ||
target remote :8080 | ||
set disassembly-flavor intel | ||
set disassemble-next-line on | ||
enable pretty-printer | ||
layout src | ||
|
||
$ gdb | ||
dblnz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
dblnz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Using VSCode to debug a Hyperlight guest | ||
|
||
To replicate the above behavior using VSCode follow the below steps: | ||
- install the `gdb` package on the host machine | ||
- install the `C/C++` extension in VSCode to add debugging capabilities | ||
- create a `.vscode/launch.json` file in the project directory with the below content: | ||
```json | ||
{ | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": "GDB", | ||
"type": "cppdbg", | ||
"request": "launch", | ||
"program": "${workspaceFolder}/src/tests/rust_guests/bin/debug/simpleguest", | ||
"args": [], | ||
"stopAtEntry": true, | ||
"hardwareBreakpoints": {"require": false, "limit": 4}, | ||
"cwd": "${workspaceFolder}", | ||
"environment": [], | ||
"externalConsole": false, | ||
"MIMode": "gdb", | ||
"miDebuggerPath": "/usr/bin/gdb", | ||
"miDebuggerServerAddress": "localhost:8080", | ||
"setupCommands": [ | ||
{ | ||
"description": "Enable pretty-printing for gdb", | ||
"text": "-enable-pretty-printing", | ||
"ignoreFailures": true | ||
}, | ||
{ | ||
"description": "Set Disassembly Flavor to Intel", | ||
"text": "-gdb-set disassembly-flavor intel", | ||
"ignoreFailures": true | ||
} | ||
] | ||
} | ||
] | ||
} | ||
``` | ||
- in `Run and Debug` tab, select the `GDB` configuration and click on the `Run` | ||
button to start the debugging session. | ||
The gdb client will connect to the Hyperlight sandbox and the guest vCPU will | ||
stop at the entry point. | ||
|
||
|
||
## How it works | ||
|
||
The gdb feature is designed to work like a Request - Response protocol between | ||
a thread that accepts commands from a gdb client and the hypervisor handler over | ||
a communication channel. | ||
|
||
All the functionality is implemented on the hypervisor side so it has access to | ||
the shared memory and the vCPU. | ||
|
||
The gdb thread uses the `gdbstub` crate to handle the communication with the gdb client. | ||
When the gdb client requests one of the supported features mentioned above, a request | ||
is sent over the communication channel to the hypervisor handler for the sandbox | ||
to resolve. | ||
|
||
Below is a sequence diagram that shows the interaction between the entities | ||
involved in the gdb debugging of a Hyperlight guest running inside a KVM sandbox. | ||
|
||
``` | ||
┌───────────────────────────────────────────────────────────────────────────────────────────────┐ | ||
│ Hyperlight Sandbox │ | ||
USER │ │ | ||
┌────────────┐ │ ┌──────────────┐ ┌───────────────────────────┐ ┌────────┐ │ | ||
│ gdb client │ │ │ gdb thread │ │ hypervisor handler thread │ │ vCPU │ │ | ||
└────────────┘ │ └──────────────┘ └───────────────────────────┘ └────────┘ │ | ||
| │ | create_gdb_thread | | │ | ||
| │ |◄─────────────────────────────────────────┌─┐ vcpu stopped ┌─┐ │ | ||
| attach │ ┌─┐ │ │◄──────────────────────────────┴─┘ │ | ||
┌─┐───────────────────────┼────────►│ │ │ │ entrypoint breakpoint | │ | ||
│ │ attach response │ │ │ │ │ | │ | ||
│ │◄──────────────────────┼─────────│ │ │ │ | │ | ||
│ │ │ │ │ │ │ | │ | ||
│ │ add_breakpoint │ │ │ │ │ | │ | ||
│ │───────────────────────┼────────►│ │ add_breakpoint │ │ | │ | ||
│ │ │ │ │────────────────────────────────────────►│ │ add_breakpoint | │ | ||
│ │ │ │ │ │ │────┐ | │ | ||
│ │ │ │ │ │ │ │ | │ | ||
│ │ │ │ │ │ │◄───┘ | │ | ||
│ │ │ │ │ add_breakpoint response │ │ | │ | ||
│ │ add_breakpoint response │ │◄────────────────────────────────────────│ │ | │ | ||
│ │◄──────────────────────┬─────────│ │ │ │ | │ | ||
│ │ continue │ │ │ │ │ | │ | ||
│ │───────────────────────┼────────►│ │ continue │ │ | │ | ||
│ │ │ │ │────────────────────────────────────────►│ │ resume vcpu | │ | ||
│ │ │ │ │ │ │──────────────────────────────►┌─┐ │ | ||
│ │ │ │ │ │ │ │ │ │ | ||
│ │ │ │ │ │ │ │ │ │ | ||
│ │ │ │ │ │ │ │ │ │ | ||
│ │ │ │ │ │ │ │ │ │ | ||
│ │ │ │ │ │ │ vcpu stopped │ │ │ | ||
│ │ │ │ │ notify vcpu stop reason │ │◄──────────────────────────────┴─┘ │ | ||
│ │ notify vcpu stop reason │ │◄────────────────────────────────────────│ │ | │ | ||
│ │◄──────────────────────┬─────────│ │ │ │ | │ | ||
│ │ continue until end │ │ │ │ │ | │ | ||
│ │───────────────────────┼────────►│ │ continue │ │ resume vcpu | │ | ||
│ │ │ │ │────────────────────────────────────────►│ │──────────────────────────────►┌─┐ │ | ||
│ │ │ │ │ │ │ │ │ │ | ||
│ │ │ │ │ comm channel disconnected │ │ vcpu halted │ │ │ | ||
│ │ target finished exec│ │ │◄────────────────────────────────────────┤ │◄──────────────────────────────┴─┘ │ | ||
│ │◄──────────────────────┼─────────┴─┘ target finished exec └─┘ | │ | ||
│ │ │ | | | │ | ||
└─┘ │ | | | │ | ||
| └───────────────────────────────────────────────────────────────────────────────────────────────┘ | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.