Skip to content

Commit af0a52a

Browse files
committed
fix issues related to clippy, typos and feedback
- improve documentation - improve gdb errors by adding a specific error variant for when the rflags conversion from u64 to u32 fails - fix clippy issue on windows Signed-off-by: Doru Blânzeanu <[email protected]>
1 parent d0db26e commit af0a52a

File tree

7 files changed

+136
-15
lines changed

7 files changed

+136
-15
lines changed

docs/how-to-debug-a-hyperlight-guest.md

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,54 @@
1-
# How to debug a Hyperlight guest
1+
# How to debug a Hyperlight guest using gdb
22

33
Hyperlight supports gdb debugging of a guest running inside a Hyperlight sandbox.
44
When Hyperlight is compiled with the `gdb` feature enabled, a Hyperlight sandbox can be configured
55
to start listening for a gdb connection.
66

7+
## Supported features
8+
9+
The Hyperlight `gdb` feature enables:
10+
11+
1. KVM guest debugging:
12+
- an entry point breakpoint is automatically set for the guest to stop
13+
- add and remove HW breakpoints (maximum 4 set breakpoints at a time)
14+
- add and remove SW breakpoints
15+
- read and write registers
16+
- read and write addresses
17+
- step/continue
18+
- get code offset from target
19+
20+
## Expected behavior
21+
22+
Below is a list describing some cases of expected behavior from a gdb debug
23+
session of a guest binary running inside a Hyperlight sandbox.
24+
25+
- when the `gdb` feature is enabled and a SandboxConfiguration is provided a
26+
debug port, the created sandbox will wait for a gdb client to connect on the
27+
configured port
28+
- when the gdb client attaches, the guest vCPU is expected to be stopped at the
29+
entrypoint
30+
- if a gdb client disconnects unexpectedly, the debug session will be closed and
31+
the guest will continue executing disregarding any prior breakpoints
32+
33+
## How it works
34+
35+
The gdb feature is designed to work like a Request - Response protocol between
36+
a thread that accepts commands from a gdb cliend and the hypervisor handler over
37+
a communication channel.
38+
39+
All the functionality is implemented on the hypervisor side so it has access to
40+
the shared memory and the vCPU.
41+
42+
The gdb thread uses the `gdbstub` crate to handle the communication with the gdb client.
43+
When the gdb client requests one of the supported features mentioned above, a request
44+
is sent over the communication channel to the hypervisor handler for the sandbox
45+
to resolve.
46+
747
## Example
8-
The snipped of a rust host application below configures the Hyperlight Sandbox to
48+
49+
### Sandbox configuration
50+
51+
The snippet of a rust host application below configures the Hyperlight Sandbox to
952
listen on port `9050` for a gdb client to connect.
1053

1154
```rust
@@ -25,17 +68,44 @@ listen on port `9050` for a gdb client to connect.
2568

2669
The execution of the guest will wait for gdb to attach.
2770

28-
One can use a simple gdb config to provide the symbols and desired configuration:
71+
### Gdb configuration
72+
73+
One can use a simple gdb config to provide the symbols and desired configuration.
74+
75+
The below contents of the `.gdbinit` file can be used to provide a basic configuration
76+
to gdb startup.
2977

30-
For the above snippet, the below contents of the `.gdbinit` file can be used to
31-
provide configuration to gdb startup.
3278
```gdb
79+
# Path to symbols
3380
file path/to/symbols.elf
81+
# The port on which Hyperlight listens for a connection
3482
target remote :9050
3583
set disassembly-flavor intel
3684
set disassemble-next-line on
3785
enable pretty-printer
3886
layout src
3987
```
40-
4188
One can find more information about the `.gdbinit` file at [gdbinit(5)](https://www.man7.org/linux/man-pages/man5/gdbinit.5.html).
89+
90+
### End to end example
91+
92+
Using the [Sandbox configuration](#sandbox-configuration) above to configure the [hello-world](https://github.com/hyperlight-dev/hyperlight/blob/main/src/hyperlight_host/examples/hello-world/main.rs) example
93+
in Hyperlight one can run the below commands to debug the guest binary:
94+
95+
```bash
96+
# Terminal 1
97+
$ cargo run --example hello-world --features gdb
98+
```
99+
100+
```bash
101+
# Terminal 2
102+
$ cat .gdbinit
103+
file file src/tests/rust_guests/bin/debug/simpleguest
104+
target remote :9050
105+
set disassembly-flavor intel
106+
set disassemble-next-line on
107+
enable pretty-printer
108+
layout src
109+
110+
$ gdb
111+
```

src/hyperlight_host/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ sha256 = "1.4.0"
7171
windows-version = "0.1"
7272

7373
[target.'cfg(unix)'.dependencies]
74-
gdbstub = "0.7.3"
75-
gdbstub_arch = "0.3.1"
74+
gdbstub = { version = "0.7.3", optional = true }
75+
gdbstub_arch = { version = "0.3.1", optional = true }
7676
seccompiler = { version = "0.4.0", optional = true }
7777
kvm-bindings = { version = "0.11", features = ["fam-wrappers"], optional = true }
7878
kvm-ioctls = { version = "0.20", optional = true }
@@ -131,7 +131,7 @@ mshv2 = ["dep:mshv-bindings2", "dep:mshv-ioctls2"]
131131
mshv3 = ["dep:mshv-bindings3", "dep:mshv-ioctls3"]
132132
inprocess = []
133133
# This enables compilation of gdb stub for easy debug in the guest
134-
gdb = []
134+
gdb = ["dep:gdbstub", "dep:gdbstub_arch"]
135135

136136
[[bench]]
137137
name = "benchmarks"

src/hyperlight_host/src/hypervisor/gdb/event_loop.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2024 The Hyperlight Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
use gdbstub::common::Signal;
218
use gdbstub::conn::ConnectionExt;
319
use gdbstub::stub::run_blocking::{self, WaitForStopReasonError};

src/hyperlight_host/src/hypervisor/gdb/mod.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2024 The Hyperlight Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
mod event_loop;
218
pub mod x86_64_target;
319

@@ -23,6 +39,8 @@ pub enum GdbTargetError {
2339
CannotReceiveMsg,
2440
#[error("Error encountered when sending message")]
2541
CannotSendMsg,
42+
#[error("Out of range conversion: {0}")]
43+
OutOfRangeConversion(String),
2644
#[error("Encountered an unexpected message over communication channel")]
2745
UnexpectedMessage,
2846
#[error("Unexpected error encountered")]
@@ -48,8 +66,8 @@ impl From<GdbTargetError> for TargetError<GdbTargetError> {
4866
}
4967
}
5068

51-
#[derive(Debug, Default)]
5269
/// Struct that contains the x86_64 core registers
70+
#[derive(Debug, Default)]
5371
pub struct X86_64Regs {
5472
pub rax: u64,
5573
pub rbx: u64,
@@ -71,17 +89,17 @@ pub struct X86_64Regs {
7189
pub rflags: u64,
7290
}
7391

74-
#[derive(Debug)]
7592
/// Defines the possible reasons for which a vCPU ce be stopped when debugging
93+
#[derive(Debug)]
7694
pub enum VcpuStopReason {
7795
DoneStep,
7896
HwBp,
7997
SwBp,
8098
Unknown,
8199
}
82100

83-
#[derive(Debug)]
84101
/// Enumerates the possible actions that a debugger can ask from a Hypervisor
102+
#[derive(Debug)]
85103
pub enum DebugMsg {
86104
AddHwBreakpoint(u64),
87105
AddSwBreakpoint(u64),
@@ -97,8 +115,8 @@ pub enum DebugMsg {
97115
WriteRegisters(X86_64Regs),
98116
}
99117

100-
#[derive(Debug)]
101118
/// Enumerates the possible responses that a hypervisor can provide to a debugger
119+
#[derive(Debug)]
102120
pub enum DebugResponse {
103121
AddHwBreakpoint(bool),
104122
AddSwBreakpoint(bool),

src/hyperlight_host/src/hypervisor/gdb/x86_64_target.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
Copyright 2024 The Hyperlight Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
117
use crossbeam_channel::TryRecvError;
218
use gdbstub::arch::Arch;
319
use gdbstub::common::Signal;
@@ -168,7 +184,7 @@ impl SingleThreadBase for HyperlightSandboxTarget {
168184
regs.regs[15] = read_regs.r15;
169185
regs.rip = read_regs.rip;
170186
regs.eflags = u32::try_from(read_regs.rflags)
171-
.expect("Couldn't convert rflags from u64 to u32");
187+
.map_err(|e| GdbTargetError::OutOfRangeConversion(e.to_string()))?;
172188

173189
Ok(())
174190
}

src/hyperlight_host/src/hypervisor/hyperv_windows.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ impl Hypervisor for HypervWindowsDriver {
374374
hv_handler,
375375
outb_hdl,
376376
mem_access_hdl,
377+
#[cfg(gdb)]
377378
dbg_mem_access_hdl,
378379
)?;
379380

src/hyperlight_host/src/hypervisor/kvm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ impl Hypervisor for KVMDriver {
925925
);
926926

927927
self.send_dbg_msg(response)
928-
.map_err(|e| new_error!("Couldn't send reponse to gdb: {:?}", e))?;
928+
.map_err(|e| new_error!("Couldn't send response to gdb: {:?}", e))?;
929929

930930
if cont {
931931
break;

0 commit comments

Comments
 (0)