From 390961899dd70b9f219979ece55b073aa23bc598 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= <dblnz@pm.me>
Date: Mon, 30 Jun 2025 20:50:36 +0300
Subject: [PATCH] gdb: fix issue "Debug not enabled" when `gdb` feature was
 enabled
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- This happened due to a message that was sent from the Hypervisor to
  the `gdb` thread even if the sandbox had no debug enabled. The
  transmission failed and returned this error.
- The fix checks a condition before sending this signal so that to
  ensure the sandbox has debugging enabled

Signed-off-by: Doru Blânzeanu <dblnz@pm.me>
---
 .../examples/guest-debugging/main.rs          | 31 +++++++++++++++++--
 .../src/hypervisor/hyperv_linux.rs            |  4 ++-
 .../src/hypervisor/hyperv_windows.rs          |  4 ++-
 src/hyperlight_host/src/hypervisor/kvm.rs     |  4 ++-
 src/tests/rust_guests/witguest/Cargo.lock     | 18 +++++------
 5 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/src/hyperlight_host/examples/guest-debugging/main.rs b/src/hyperlight_host/examples/guest-debugging/main.rs
index 42b97598d..f33ed511f 100644
--- a/src/hyperlight_host/examples/guest-debugging/main.rs
+++ b/src/hyperlight_host/examples/guest-debugging/main.rs
@@ -41,14 +41,27 @@ fn get_sandbox_cfg() -> Option<SandboxConfiguration> {
 fn main() -> hyperlight_host::Result<()> {
     let cfg = get_sandbox_cfg();
 
+    // Create an uninitialized sandbox with a guest binary and debug enabled
+    let mut uninitialized_sandbox_dbg = UninitializedSandbox::new(
+        hyperlight_host::GuestBinary::FilePath(
+            hyperlight_testing::simple_guest_as_string().unwrap(),
+        ),
+        cfg, // sandbox configuration
+    )?;
+
     // Create an uninitialized sandbox with a guest binary
     let mut uninitialized_sandbox = UninitializedSandbox::new(
         hyperlight_host::GuestBinary::FilePath(
             hyperlight_testing::simple_guest_as_string().unwrap(),
         ),
-        cfg, // sandbox configuration
+        None, // sandbox configuration
     )?;
 
+    // Register a host functions
+    uninitialized_sandbox_dbg.register("Sleep5Secs", || {
+        thread::sleep(std::time::Duration::from_secs(5));
+        Ok(())
+    })?;
     // Register a host functions
     uninitialized_sandbox.register("Sleep5Secs", || {
         thread::sleep(std::time::Duration::from_secs(5));
@@ -56,11 +69,23 @@ fn main() -> hyperlight_host::Result<()> {
     })?;
     // Note: This function is unused, it's just here for demonstration purposes
 
-    // Initialize sandbox to be able to call host functions
+    // Initialize sandboxes to be able to call host functions
+    let mut multi_use_sandbox_dbg: MultiUseSandbox =
+        uninitialized_sandbox_dbg.evolve(Noop::default())?;
     let mut multi_use_sandbox: MultiUseSandbox = uninitialized_sandbox.evolve(Noop::default())?;
 
     // Call guest function
-    let message = "Hello, World! I am executing inside of a VM :)\n".to_string();
+    let message =
+        "Hello, World! I am executing inside of a VM with debugger attached :)\n".to_string();
+    multi_use_sandbox_dbg
+        .call_guest_function_by_name::<i32>(
+            "PrintOutput", // function must be defined in the guest binary
+            message.clone(),
+        )
+        .unwrap();
+
+    let message =
+        "Hello, World! I am executing inside of a VM without debugger attached :)\n".to_string();
     multi_use_sandbox
         .call_guest_function_by_name::<i32>(
             "PrintOutput", // function must be defined in the guest binary
diff --git a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs
index db3f81c9b..db5037106 100644
--- a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs
+++ b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs
@@ -441,7 +441,9 @@ impl HypervLinuxDriver {
         // Send the interrupt handle to the GDB thread if debugging is enabled
         // This is used to allow the GDB thread to stop the vCPU
         #[cfg(gdb)]
-        hv.send_dbg_msg(DebugResponse::InterruptHandle(interrupt_handle))?;
+        if hv.debug.is_some() {
+            hv.send_dbg_msg(DebugResponse::InterruptHandle(interrupt_handle))?;
+        }
 
         Ok(hv)
     }
diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs
index 0d6d794bc..288b5bf5b 100644
--- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs
+++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs
@@ -356,7 +356,9 @@ impl HypervWindowsDriver {
         // Send the interrupt handle to the GDB thread if debugging is enabled
         // This is used to allow the GDB thread to stop the vCPU
         #[cfg(gdb)]
-        hv.send_dbg_msg(DebugResponse::InterruptHandle(interrupt_handle))?;
+        if hv.debug.is_some() {
+            hv.send_dbg_msg(DebugResponse::InterruptHandle(interrupt_handle))?;
+        }
 
         Ok(hv)
     }
diff --git a/src/hyperlight_host/src/hypervisor/kvm.rs b/src/hyperlight_host/src/hypervisor/kvm.rs
index d6b348cc0..d85a6a838 100644
--- a/src/hyperlight_host/src/hypervisor/kvm.rs
+++ b/src/hyperlight_host/src/hypervisor/kvm.rs
@@ -395,7 +395,9 @@ impl KVMDriver {
         // Send the interrupt handle to the GDB thread if debugging is enabled
         // This is used to allow the GDB thread to stop the vCPU
         #[cfg(gdb)]
-        hv.send_dbg_msg(DebugResponse::InterruptHandle(interrupt_handle))?;
+        if hv.debug.is_some() {
+            hv.send_dbg_msg(DebugResponse::InterruptHandle(interrupt_handle))?;
+        }
 
         Ok(hv)
     }
diff --git a/src/tests/rust_guests/witguest/Cargo.lock b/src/tests/rust_guests/witguest/Cargo.lock
index 478740f35..a1edc4b10 100644
--- a/src/tests/rust_guests/witguest/Cargo.lock
+++ b/src/tests/rust_guests/witguest/Cargo.lock
@@ -178,7 +178,7 @@ dependencies = [
 
 [[package]]
 name = "hyperlight-common"
-version = "0.6.1"
+version = "0.7.0"
 dependencies = [
  "anyhow",
  "flatbuffers",
@@ -188,7 +188,7 @@ dependencies = [
 
 [[package]]
 name = "hyperlight-component-macro"
-version = "0.6.1"
+version = "0.7.0"
 dependencies = [
  "env_logger",
  "hyperlight-component-util",
@@ -202,7 +202,7 @@ dependencies = [
 
 [[package]]
 name = "hyperlight-component-util"
-version = "0.6.1"
+version = "0.7.0"
 dependencies = [
  "itertools",
  "log",
@@ -215,7 +215,7 @@ dependencies = [
 
 [[package]]
 name = "hyperlight-guest"
-version = "0.6.1"
+version = "0.7.0"
 dependencies = [
  "anyhow",
  "hyperlight-common",
@@ -224,7 +224,7 @@ dependencies = [
 
 [[package]]
 name = "hyperlight-guest-bin"
-version = "0.6.1"
+version = "0.7.0"
 dependencies = [
  "buddy_system_allocator",
  "cc",
@@ -337,9 +337,9 @@ dependencies = [
 
 [[package]]
 name = "prettyplease"
-version = "0.2.34"
+version = "0.2.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6837b9e10d61f45f987d50808f83d1ee3d206c66acf650c3e4ae2e1f6ddedf55"
+checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a"
 dependencies = [
  "proc-macro2",
  "syn",
@@ -477,9 +477,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.103"
+version = "2.0.104"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
+checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
 dependencies = [
  "proc-macro2",
  "quote",
