From 9677a30c9a87cd6d2aae3c6d450792418bc12c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= Date: Thu, 24 Jul 2025 00:29:32 +0300 Subject: [PATCH 1/5] Enable native debugging for wasm modules/components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Doru Blânzeanu --- .vscode/launch.json | 106 +++++++++++---- Cargo.lock | 40 ++++++ Justfile | 18 +-- src/hyperlight_wasm/Cargo.toml | 8 ++ src/hyperlight_wasm/build.rs | 12 +- .../examples/guest-debugging/main.rs | 122 ++++++++++++++++++ .../scripts/build-wasm-examples.sh | 77 ++++++++--- .../src/sandbox/sandbox_builder.rs | 22 ++++ src/hyperlight_wasm_aot/Cargo.toml | 3 + src/hyperlight_wasm_aot/src/main.rs | 12 ++ src/rust_wasm_samples/build.rs | 1 - src/wasm_runtime/Cargo.lock | 12 ++ src/wasm_runtime/Cargo.toml | 4 + src/wasm_runtime/build.rs | 4 + src/wasm_runtime/src/component.rs | 2 + src/wasm_runtime/src/module.rs | 2 + 16 files changed, 394 insertions(+), 51 deletions(-) create mode 100644 src/hyperlight_wasm/examples/guest-debugging/main.rs diff --git a/.vscode/launch.json b/.vscode/launch.json index 01cb304b..cf6632a1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,34 +1,96 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - // this can be used to debug tests - "version": "0.2.0", + "inputs": [ + { + "id": "program", + "type": "promptString", + "default": "x64/debug/wasm_runtime", + "description": "Path to the program to debug", + } + ], "configurations": [ { "type": "lldb", "request": "launch", - "name": "Cargo test", + "name": "Debug example 'guest-debugging'", + "cargo": { + "args": [ + "build", + "--example=guest-debugging", + "--package=hyperlight-wasm", + "--features=gdb", + ], + "filter": { + "name": "guest-debugging", + "kind": "example" + } + }, + "env": { + "RUST_DIR_FOR_DEBUGGING_TESTS": "${workspaceFolder}/src/hyperlight_wasm", + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug example 'rust_wasm_examples'", "cargo": { - "args": [ - "test", - "--profile=dev", - "--lib", - "--no-run" - - ], - "filter": { - "name": "hyperlight_wasm", - "kind": "lib" - } + "args": [ + "build", + "--example=rust_wasm_examples", + "--package=hyperlight-wasm", + ], + "filter": { + "name": "rust_wasm_examples", + "kind": "example" + } }, "env": { - "RUST_DIR_FOR_DEBUGGING_TESTS": "${workspaceFolder}/src/hyperlight_wasm" + "RUST_DIR_FOR_DEBUGGING_TESTS": "${workspaceFolder}/src/hyperlight_wasm", + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "name": "Remote GDB attach", + "type": "cppdbg", + "request": "launch", + "program": "${input:program}", + "args": [], + "stopAtEntry": true, + "hardwareBreakpoints": { + "require": false, + "limit": 4 }, - "args": [ - "--exact", - "sandbox::loaded_wasm_sandbox::tests::test_call_host_func_with_vecbytes" + "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 + }, ] - } + }, + { + "name": "Remote LLDB attach", + "type": "lldb", + "request": "launch", + "targetCreateCommands": [ + "target create ${input:program}", + ], + "processCreateCommands": [ + "gdb-remote localhost:8080" + ], + }, ] } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index eed6eff4..4320862d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1007,6 +1007,30 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "gdbstub" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b686b198dfaa4109ebd0443d2841bc521e4b4b2915f1d84b3bb50332a8cdc1ae" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "log", + "managed", + "num-traits", + "paste", +] + +[[package]] +name = "gdbstub_arch" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22dde0e1b68787036ccedd0b1ff6f953527a0e807e571fbe898975203027278f" +dependencies = [ + "gdbstub", + "num-traits", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1318,6 +1342,8 @@ dependencies = [ "crossbeam-channel", "elfcore", "flatbuffers", + "gdbstub", + "gdbstub_arch", "goblin", "hyperlight-common", "kvm-bindings", @@ -1357,9 +1383,11 @@ dependencies = [ "blake3", "built", "cfg-if", + "cfg_aliases", "chrono", "criterion", "crossbeam-queue", + "env_logger", "examples_common", "goblin", "hyperlight-component-macro", @@ -1753,6 +1781,12 @@ dependencies = [ "libc", ] +[[package]] +name = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + [[package]] name = "memchr" version = "2.7.6" @@ -2023,6 +2057,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "percent-encoding" version = "2.3.2" diff --git a/Justfile b/Justfile index 9d3adf83..7b4a226a 100644 --- a/Justfile +++ b/Justfile @@ -19,7 +19,7 @@ ensure-tools: cargo install cargo-component --locked --version 0.21.1 cargo install wit-bindgen-cli --locked --version 0.43.0 -build-all target=default-target: (build target) (build-wasm-examples target) (build-rust-wasm-examples target) (build-rust-component-examples target) (build-wasm-runtime target) +build-all target=default-target features="": (build target features) (build-wasm-examples target features) (build-rust-wasm-examples target features) (build-rust-component-examples target) (build-wasm-runtime target features) build target=default-target features="": (fmt-check) cargo build {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --verbose --profile={{ if target == "debug" {"dev"} else { target } }} @@ -32,23 +32,23 @@ compile-wit: wasm-tools component wit ./src/wasmsamples/components/runcomponent.wit -w -o ./src/wasmsamples/components/runcomponent-world.wasm wasm-tools component wit ./src/component_sample/wit/example.wit -w -o ./src/component_sample/wit/component-world.wasm -build-wasm-runtime target=default-target: - cd ./src/wasm_runtime && cargo build --verbose --profile={{ if target == "debug" {"dev"} else { target } }} && rm -R target +build-wasm-runtime target=default-target features="": + cd ./src/wasm_runtime && cargo build --verbose {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} --profile={{ if target == "debug" {"dev"} else { target } }} && rm -R target -build-wasm-examples target=default-target: (compile-wit) - {{ build-wasm-examples-command }} {{target}} +build-wasm-examples target=default-target features="": (compile-wit) + {{ build-wasm-examples-command }} {{target}} {{features}} -build-rust-wasm-examples target=default-target: (mkdir-redist target) +build-rust-wasm-examples target=default-target features="": (mkdir-redist target) rustup target add wasm32-unknown-unknown cd ./src/rust_wasm_samples && cargo build --target wasm32-unknown-unknown --profile={{ if target == "debug" {"dev"} else { target } }} - cargo run -p hyperlight-wasm-aot compile ./src/rust_wasm_samples/target/wasm32-unknown-unknown/{{ target }}/rust_wasm_samples.wasm ./x64/{{ target }}/rust_wasm_samples.aot + cargo run {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} -p hyperlight-wasm-aot compile ./src/rust_wasm_samples/target/wasm32-unknown-unknown/{{ target }}/rust_wasm_samples.wasm ./x64/{{ target }}/rust_wasm_samples.aot -build-rust-component-examples target=default-target: (compile-wit) +build-rust-component-examples target=default-target features="": (compile-wit) # use cargo component so we don't get all the wasi imports https://github.com/bytecodealliance/cargo-component?tab=readme-ov-file#relationship-with-wasm32-wasip2 # we also explicitly target wasm32-unknown-unknown since cargo component might try to pull in wasi imports https://github.com/bytecodealliance/cargo-component/issues/290 rustup target add wasm32-unknown-unknown cd ./src/component_sample && cargo component build --target wasm32-unknown-unknown --profile={{ if target == "debug" {"dev"} else { target } }} - cargo run -p hyperlight-wasm-aot compile --component ./src/component_sample/target/wasm32-unknown-unknown/{{ target }}/component_sample.wasm ./x64/{{ target }}/component_sample.aot + cargo run {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--features " + features } }} -p hyperlight-wasm-aot compile --component ./src/component_sample/target/wasm32-unknown-unknown/{{ target }}/component_sample.wasm ./x64/{{ target }}/component_sample.aot check target=default-target: cargo check --profile={{ if target == "debug" {"dev"} else { target } }} diff --git a/src/hyperlight_wasm/Cargo.toml b/src/hyperlight_wasm/Cargo.toml index c8dfcc46..48781bb7 100644 --- a/src/hyperlight_wasm/Cargo.toml +++ b/src/hyperlight_wasm/Cargo.toml @@ -29,6 +29,11 @@ name = "helloworld" path = "examples/helloworld/main.rs" test = true +[[example]] +name = "guest-debugging" +path = "examples/guest-debugging/main.rs" +test = true + [[example]] name = "hostfuncs" path = "examples/hostfuncs/main.rs" @@ -52,6 +57,7 @@ tracing = "0.1.27" log = "0.4.28" cfg-if = { version = "1" } metrics = "0.24.2" +env_logger = "0.11.8" [target.'cfg(windows)'.dependencies] windows = { version = "0.62", features = ["Win32_System_Threading"] } @@ -68,6 +74,7 @@ metrics-util = "0.20.0" metrics-exporter-prometheus = "0.17" [build-dependencies] +cfg_aliases = "0.2.1" chrono = "0.4" blake3 = "1.8" built = { version = "0.8.0", features = ["chrono", "git2"] } @@ -81,6 +88,7 @@ function_call_metrics = ["hyperlight-host/function_call_metrics"] seccomp = ["hyperlight-host/seccomp"] print_debug = ["hyperlight-host/print_debug"] crashdump = ["hyperlight-host/crashdump"] +gdb = ["hyperlight-host/gdb"] kvm = ["hyperlight-host/kvm"] mshv2 = ["hyperlight-host/mshv2"] mshv3 = ["hyperlight-host/mshv3"] diff --git a/src/hyperlight_wasm/build.rs b/src/hyperlight_wasm/build.rs index 75ac7f96..5b942123 100644 --- a/src/hyperlight_wasm/build.rs +++ b/src/hyperlight_wasm/build.rs @@ -125,7 +125,7 @@ fn build_wasm_runtime() -> PathBuf { env_vars.retain(|(key, _)| !key.starts_with("CARGO_")); let mut cargo_cmd = std::process::Command::new(&cargo_bin); - let cmd = cargo_cmd + let mut cmd = cargo_cmd .arg("build") .arg("--profile") .arg(cargo_profile) @@ -137,6 +137,12 @@ fn build_wasm_runtime() -> PathBuf { .envs(env_vars) .env("PATH", path_with(&toolchain_dir)) .env("HYPERLIGHT_GUEST_TOOLCHAIN_ROOT", &toolchain_dir); + + // Add --features gdb if the gdb feature is enabled for this build script + if std::env::var("CARGO_FEATURE_GDB").is_ok() { + cmd = cmd.arg("--features").arg("gdb"); + } + let status = cmd .status() .unwrap_or_else(|e| panic!("could not run cargo build wasm_runtime: {}", e)); @@ -239,5 +245,9 @@ fn main() -> Result<()> { println!("cargo:rerun-if-changed=build.rs"); + cfg_aliases::cfg_aliases! { + gdb: { all(feature = "gdb", debug_assertions) }, + } + Ok(()) } diff --git a/src/hyperlight_wasm/examples/guest-debugging/main.rs b/src/hyperlight_wasm/examples/guest-debugging/main.rs new file mode 100644 index 00000000..b1070ce8 --- /dev/null +++ b/src/hyperlight_wasm/examples/guest-debugging/main.rs @@ -0,0 +1,122 @@ +/* +Copyright 2025 The Hyperlight Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +//! Example demonstrating how to enable guest debugging in a Wasm sandbox +//! +//! The prerequisite for this example is to have a Wasm modules compiled with debug +//! symbols. +//! +//! To compile the necessary Wasm modules with debug symbols, you can use the following commands: +//! ```sh +//! # for C modules +//! just build-wasm-examples debug gdb +//! # for Rust modules +//! just build-rust-wasm-samples debug gdb +//! ``` +//! +//! # Running the Example +//! To run the example with GDB support, execute the following command: +//! ```sh +//! cargo run --example guest-debugging --features gdb +//! ``` +//! +//! This will start the example and enable debugging on port 8080. +//! You can then connect to the running Wasm guest using GDB or LLDB. +//! Check docs/wasm-modules-debugging.md for more details on how to connect the debugger. +//! +//! NOTE: The guest binary containing the wasm runtime needs to be used initially to attach +//! with the debugger. The path to the binary is written to the terminal when the example +//! is built. + +use examples_common::get_wasm_module_path; +use hyperlight_host::HyperlightError; +use hyperlight_wasm::{LoadedWasmSandbox, Result, SandboxBuilder}; + +fn get_time_since_boot_microsecond() -> Result { + let res = std::time::SystemTime::now() + .duration_since(std::time::SystemTime::UNIX_EPOCH)? + .as_micros(); + i64::try_from(res).map_err(HyperlightError::IntConversionFailure) +} + +fn builder() -> SandboxBuilder { + #[cfg(gdb)] + { + SandboxBuilder::new() + .with_guest_input_buffer_size(2 * 1024 * 1024) // 2 MiB + .with_guest_heap_size(10 * 1024 * 1024) // 4 MiB + .with_debugging_enabled(8080) // debugging on port 8080 + } + #[cfg(not(gdb))] + SandboxBuilder::new() +} + +fn main() -> Result<()> { + type TestFn = fn(&mut LoadedWasmSandbox, &str, &str) -> Result; + let tests: &[(&str, &str, TestFn)] = &[ + ("HelloWorld.aot", "HelloWorld", |sb, func_name, module| { + println!("Calling {} into \"{}\" module", func_name, module); + sb.call_guest_function( + func_name, + "Message from C Example to Wasm Function".to_string(), + ) + }), + ("rust_wasm_samples.aot", "add", |sb, func_name, module| { + println!("Calling {} into \"{}\" module", func_name, module); + let res = sb.call_guest_function(func_name, (5i32, 3i32)); + if let Ok(sum) = res { + println!("add(5, 3) = {}", sum); + } + res + }), + ( + "rust_wasm_samples.aot", + "call_host_function", + |sb, func_name, module| { + println!("Calling {} into \"{}\" module", func_name, module); + let res = sb.call_guest_function(func_name, 5i32); + if let Ok(val) = res { + println!("call_host_function(5) = {}", val); + } + res + }, + ), + ]; + let mut sandbox = builder().build()?; + let host_func = |a: i32| { + println!("host_func called with {}", a); + a + 1 + }; + + sandbox.register("TestHostFunc", host_func)?; + sandbox.register( + "GetTimeSinceBootMicrosecond", + get_time_since_boot_microsecond, + )?; + let mut wasm_sandbox = Some(sandbox.load_runtime()?); + + for (module, fn_name, func) in tests.iter() { + let mod_path = get_wasm_module_path(module)?; + + // Load a Wasm module into the sandbox + let mut loaded_wasm_sandbox = wasm_sandbox.take().unwrap().load_module(mod_path)?; + + let _ = func(&mut loaded_wasm_sandbox, fn_name, module)?; + + wasm_sandbox = Some(loaded_wasm_sandbox.unload_module()?); + } + Ok(()) +} diff --git a/src/hyperlight_wasm/scripts/build-wasm-examples.sh b/src/hyperlight_wasm/scripts/build-wasm-examples.sh index ae0e29cf..d28932b1 100755 --- a/src/hyperlight_wasm/scripts/build-wasm-examples.sh +++ b/src/hyperlight_wasm/scripts/build-wasm-examples.sh @@ -6,9 +6,23 @@ set -o pipefail pushd "$(dirname "${BASH_SOURCE[0]}")/../../wasmsamples" OUTPUT_DIR="../../x64/${1:-"debug"}" +BUILD_TYPE="${1:-"debug"}" +FEATURES="${2:-""}" mkdir -p ${OUTPUT_DIR} OUTPUT_DIR=$(realpath $OUTPUT_DIR) +# Set stripping flags based on whether features are enabled +if [ -n "$FEATURES" ]; then + AOT_FEATURES="--features $FEATURES" + STRIP_FLAGS="" + DEBUG_FLAGS="-g" + OPT_FLAGS="-O0" +else + AOT_FEATURES="" + STRIP_FLAGS="-Wl,--strip-all" + DEBUG_FLAGS="" + OPT_FLAGS="-O3" +fi if [ -f "/.dockerenv" ] || grep -q docker /proc/1/cgroup; then # running in a container so use the installed wasi-sdk as the devcontainer has this installed @@ -16,9 +30,9 @@ if [ -f "/.dockerenv" ] || grep -q docker /proc/1/cgroup; then do echo Building ${FILENAME} # Build the wasm file with wasi-libc for wasmtime - /opt/wasi-sdk/bin/clang -flto -ffunction-sections -mexec-model=reactor -O3 -z stack-size=4096 -Wl,--initial-memory=65536 -Wl,--export=__data_end -Wl,--export=__heap_base,--export=malloc,--export=free,--export=__wasm_call_ctors -Wl,--strip-all,--no-entry -Wl,--allow-undefined -Wl,--gc-sections -o ${OUTPUT_DIR}/${FILENAME%.*}-wasi-libc.wasm ${FILENAME} + /opt/wasi-sdk/bin/clang ${DEBUG_FLAGS} -flto -ffunction-sections -mexec-model=reactor ${OPT_FLAGS} -z stack-size=4096 -Wl,--initial-memory=65536 -Wl,--export=__data_end -Wl,--export=__heap_base,--export=malloc,--export=free,--export=__wasm_call_ctors ${STRIP_FLAGS} -Wl,--no-entry -Wl,--allow-undefined -Wl,--gc-sections -o ${OUTPUT_DIR}/${FILENAME%.*}-wasi-libc.wasm ${FILENAME} - cargo run -p hyperlight-wasm-aot compile ${OUTPUT_DIR}/${FILENAME%.*}-wasi-libc.wasm ${OUTPUT_DIR}/${FILENAME%.*}.aot + cargo run ${AOT_FEATURES} -p hyperlight-wasm-aot compile ${OUTPUT_DIR}/${FILENAME%.*}-wasi-libc.wasm ${OUTPUT_DIR}/${FILENAME%.*}.aot done for WIT_FILE in ${PWD}/components/*.wit; do @@ -30,16 +44,16 @@ if [ -f "/.dockerenv" ] || grep -q docker /proc/1/cgroup; then # Build the wasm file with wasi-libc for wasmtime /opt/wasi-sdk/bin/wasm32-wasip2-clang \ - -ffunction-sections -mexec-model=reactor -O3 -z stack-size=4096 \ + -ffunction-sections -mexec-model=reactor ${OPT_FLAGS} -z stack-size=4096 \ -Wl,--initial-memory=65536 -Wl,--export=__data_end -Wl,--export=__heap_base,--export=malloc,--export=free,--export=__wasm_call_ctors \ - -Wl,--strip-all,--no-entry -Wl,--allow-undefined -Wl,--gc-sections \ + ${STRIP_FLAGS} -Wl,--no-entry -Wl,--allow-undefined -Wl,--gc-sections \ -o ${OUTPUT_DIR}/${COMPONENT_NAME}-p2.wasm \ ${PWD}/components/${COMPONENT_NAME}.c \ ${PWD}/components/bindings/${COMPONENT_NAME}.c \ ${PWD}/components/bindings/${COMPONENT_NAME}_component_type.o # Build AOT for Wasmtime - cargo run -p hyperlight-wasm-aot compile --component ${OUTPUT_DIR}/${COMPONENT_NAME}-p2.wasm ${OUTPUT_DIR}/${COMPONENT_NAME}.aot + cargo run ${AOT_FEATURES} -p hyperlight-wasm-aot compile --component ${OUTPUT_DIR}/${COMPONENT_NAME}-p2.wasm ${OUTPUT_DIR}/${COMPONENT_NAME}.aot done else @@ -55,10 +69,20 @@ else for FILENAME in $(find . -name '*.c' -not -path './components/*') do echo Building ${FILENAME} - # Build the wasm file with wasi-libc for wasmtime - docker run --rm -i -v "${PWD}:/tmp/host" -v "${OUTPUT_DIR}:/tmp/output/" wasm-clang-builder:latest /opt/wasi-sdk/bin/clang -flto -ffunction-sections -mexec-model=reactor -O3 -z stack-size=4096 -Wl,--initial-memory=65536 -Wl,--export=__data_end -Wl,--export=__heap_base,--export=malloc,--export=free,--export=__wasm_call_ctors -Wl,--strip-all,--no-entry -Wl,--allow-undefined -Wl,--gc-sections -o /tmp/output/${FILENAME%.*}-wasi-libc.wasm /tmp/host/${FILENAME} - - cargo run -p hyperlight-wasm-aot compile ${OUTPUT_DIR}/${FILENAME%.*}-wasi-libc.wasm ${OUTPUT_DIR}/${FILENAME%.*}.aot + OUTPUT_WASM="${OUTPUT_DIR}/${FILENAME%.*}-wasi-libc.wasm" + ABS_INPUT="$(realpath ${FILENAME})" + ABS_OUTPUT="$(realpath ${OUTPUT_WASM})" + INPUT_DIR="$(dirname ${ABS_INPUT})" + OUTPUT_DIR_REAL="$(dirname ${ABS_OUTPUT})" + INPUT_BASE="$(basename ${ABS_INPUT})" + OUTPUT_BASE="$(basename ${ABS_OUTPUT})" + # Map parent directories to the same path in the container + docker run --rm -i \ + -v "${INPUT_DIR}:${INPUT_DIR}" \ + -v "${OUTPUT_DIR_REAL}:${OUTPUT_DIR_REAL}" \ + wasm-clang-builder:latest /bin/bash -c "/opt/wasi-sdk/bin/clang ${DEBUG_FLAGS} -flto -ffunction-sections -mexec-model=reactor ${OPT_FLAGS} -z stack-size=4096 -Wl,--initial-memory=65536 -Wl,--export=__data_end -Wl,--export=__heap_base,--export=malloc,--export=free,--export=__wasm_call_ctors ${STRIP_FLAGS} -Wl,--no-entry -Wl,--allow-undefined -Wl,--gc-sections -o ${ABS_OUTPUT} ${ABS_INPUT}" + + cargo run ${AOT_FEATURES} -p hyperlight-wasm-aot compile ${OUTPUT_WASM} ${OUTPUT_DIR}/${FILENAME%.*}.aot done echo Building components @@ -70,18 +94,35 @@ else # Generate bindings for the component wit-bindgen c ${WIT_FILE} --out-dir ${PWD}/components/bindings - # Build the wasm file with wasi-libc for wasmtime - docker run --rm -i -v "${PWD}:/tmp/host" -v "${OUTPUT_DIR}:/tmp/output/" wasm-clang-builder:latest /opt/wasi-sdk/bin/wasm32-wasip2-clang \ - -ffunction-sections -mexec-model=reactor -O3 -z stack-size=4096 \ + COMPONENT_C="${PWD}/components/${COMPONENT_NAME}.c" + BINDINGS_C="${PWD}/components/bindings/${COMPONENT_NAME}.c" + BINDINGS_TYPE_O="${PWD}/components/bindings/${COMPONENT_NAME}_component_type.o" + OUTPUT_WASM="${OUTPUT_DIR}/${COMPONENT_NAME}-p2.wasm" + ABS_COMPONENT_C="$(realpath ${COMPONENT_C})" + ABS_BINDINGS_C="$(realpath ${BINDINGS_C})" + ABS_BINDINGS_TYPE_O="$(realpath ${BINDINGS_TYPE_O})" + ABS_OUTPUT_WASM="$(realpath ${OUTPUT_WASM})" + COMPONENT_C_DIR="$(dirname ${ABS_COMPONENT_C})" + BINDINGS_C_DIR="$(dirname ${ABS_BINDINGS_C})" + BINDINGS_TYPE_O_DIR="$(dirname ${ABS_BINDINGS_TYPE_O})" + OUTPUT_WASM_DIR="$(dirname ${ABS_OUTPUT_WASM})" + # Map all parent directories to the same path in the container + docker run --rm -i \ + -v "${COMPONENT_C_DIR}:${COMPONENT_C_DIR}" \ + -v "${BINDINGS_C_DIR}:${BINDINGS_C_DIR}" \ + -v "${BINDINGS_TYPE_O_DIR}:${BINDINGS_TYPE_O_DIR}" \ + -v "${OUTPUT_WASM_DIR}:${OUTPUT_WASM_DIR}" \ + wasm-clang-builder:latest /bin/bash -c "/opt/wasi-sdk/bin/wasm32-wasip2-clang \ + -ffunction-sections -mexec-model=reactor ${OPT_FLAGS} -z stack-size=4096 \ -Wl,--initial-memory=65536 -Wl,--export=__data_end -Wl,--export=__heap_base,--export=malloc,--export=free,--export=__wasm_call_ctors \ - -Wl,--strip-all,--no-entry -Wl,--allow-undefined -Wl,--gc-sections \ - -o /tmp/output/${COMPONENT_NAME}-p2.wasm \ - /tmp/host/components/${COMPONENT_NAME}.c \ - /tmp/host/components/bindings/${COMPONENT_NAME}.c \ - /tmp/host/components/bindings/${COMPONENT_NAME}_component_type.o + ${STRIP_FLAGS} -Wl,--no-entry -Wl,--allow-undefined -Wl,--gc-sections \ + -o ${ABS_OUTPUT_WASM} \ + ${ABS_COMPONENT_C} \ + ${ABS_BINDINGS_C} \ + ${ABS_BINDINGS_TYPE_O}" # Build AOT for Wasmtime - cargo run -p hyperlight-wasm-aot compile --component ${OUTPUT_DIR}/${COMPONENT_NAME}-p2.wasm ${OUTPUT_DIR}/${COMPONENT_NAME}.aot + cargo run ${AOT_FEATURES} -p hyperlight-wasm-aot compile --component ${OUTPUT_WASM} ${OUTPUT_DIR}/${COMPONENT_NAME}.aot done fi diff --git a/src/hyperlight_wasm/src/sandbox/sandbox_builder.rs b/src/hyperlight_wasm/src/sandbox/sandbox_builder.rs index 7eef21e5..63726a44 100644 --- a/src/hyperlight_wasm/src/sandbox/sandbox_builder.rs +++ b/src/hyperlight_wasm/src/sandbox/sandbox_builder.rs @@ -46,6 +46,28 @@ impl SandboxBuilder { } } + /// Enable debugging for the guest + /// This will allow the guest to be natively debugged using GDB or other debugging tools + /// + /// # Example: + /// ```rust + /// use hyperlight_host::sandbox::SandboxBuilder; + /// let sandbox = SandboxBuilder::new() + /// .with_debugging_enabled(8080) // Enable debugging on port 8080 + /// .build() + /// .expect("Failed to build sandbox"); + /// ``` + /// # Note: + /// This feature is only available when the `gdb` feature is enabled. + /// If the `gdb` feature is not enabled, this method will have no effect. + #[cfg(gdb)] + pub fn with_debugging_enabled(mut self, port: u16) -> Self { + let debug_info = hyperlight_host::sandbox::config::DebugInfo { port }; + self.config.set_guest_debug_info(debug_info); + + self + } + /// Set the host print function pub fn with_host_print_fn( mut self, diff --git a/src/hyperlight_wasm_aot/Cargo.toml b/src/hyperlight_wasm_aot/Cargo.toml index 89dad01c..ac2fb8b3 100644 --- a/src/hyperlight_wasm_aot/Cargo.toml +++ b/src/hyperlight_wasm_aot/Cargo.toml @@ -16,3 +16,6 @@ wasmtime = { version = "36.0.2", default-features = false, features = ["cranelif clap = "4.5" cargo_metadata = "0.23" cargo-util-schemas = "0.10.0" + +[features] +gdb = ["wasmtime/debug-builtins"] diff --git a/src/hyperlight_wasm_aot/src/main.rs b/src/hyperlight_wasm_aot/src/main.rs index 6d6dd643..93578e87 100644 --- a/src/hyperlight_wasm_aot/src/main.rs +++ b/src/hyperlight_wasm_aot/src/main.rs @@ -19,7 +19,10 @@ use std::path::Path; use cargo_metadata::{MetadataCommand, Package}; use cargo_util_schemas::manifest::PackageName; use clap::{Arg, Command}; +#[cfg(feature = "gdb")] +use wasmtime::OptLevel; use wasmtime::{Config, Engine, Module, Precompiled}; + fn main() { let hyperlight_wasm_aot_version = env!("CARGO_PKG_VERSION"); let matches = Command::new("hyperlight-wasm-aot") @@ -149,8 +152,17 @@ fn main() { } } +/// Returns a new `Config` for the Wasmtime engine with additional settings for AOT compilation. fn get_config() -> Config { let mut config = Config::new(); config.target("x86_64-unknown-none").unwrap(); + + // Enable the default features for the Wasmtime engine. + #[cfg(feature = "gdb")] + { + config.debug_info(true); + config.cranelift_opt_level(OptLevel::None); + } + config } diff --git a/src/rust_wasm_samples/build.rs b/src/rust_wasm_samples/build.rs index 93ce36a9..45c026ac 100644 --- a/src/rust_wasm_samples/build.rs +++ b/src/rust_wasm_samples/build.rs @@ -17,6 +17,5 @@ limitations under the License. fn main() { println!("cargo:rustc-link-arg=-zstack-size=4096"); println!("cargo:rustc-link-arg=--initial-memory=65536"); - println!("cargo:rustc-link-arg=--strip-all"); println!("cargo:rustc-target-feature=+bulk-memory"); } diff --git a/src/wasm_runtime/Cargo.lock b/src/wasm_runtime/Cargo.lock index fd679509..6f7ccd49 100644 --- a/src/wasm_runtime/Cargo.lock +++ b/src/wasm_runtime/Cargo.lock @@ -1808,6 +1808,7 @@ dependencies = [ "cargo_metadata", "cc", "cfg-if", + "cfg_aliases", "hyperlight-common", "hyperlight-guest", "hyperlight-guest-bin", @@ -1886,6 +1887,7 @@ dependencies = [ "wasmtime-internal-component-macro", "wasmtime-internal-component-util", "wasmtime-internal-cranelift", + "wasmtime-internal-jit-debug", "wasmtime-internal-math", "wasmtime-internal-slab", "wasmtime-internal-unwinder", @@ -1976,6 +1978,16 @@ dependencies = [ "wasmtime-internal-versioned-export-macros", ] +[[package]] +name = "wasmtime-internal-jit-debug" +version = "36.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e03f0b11f8fe4d456feac11e7e9dc6f02ddb34d4f6a1912775dbc63c5bdd5670" +dependencies = [ + "cc", + "wasmtime-internal-versioned-export-macros", +] + [[package]] name = "wasmtime-internal-math" version = "36.0.2" diff --git a/src/wasm_runtime/Cargo.toml b/src/wasm_runtime/Cargo.toml index 37065fee..0fd77c37 100644 --- a/src/wasm_runtime/Cargo.toml +++ b/src/wasm_runtime/Cargo.toml @@ -19,9 +19,13 @@ hyperlight-wasm-macro = { path = "../hyperlight_wasm_macro" } spin = "0.10.0" [build-dependencies] +cfg_aliases = "0.2.1" cc = "1.2" cfg-if = { version = "1" } cargo_metadata = "0.23" reqwest = {version = "0.12", default-features = false, features = ["blocking","rustls-tls"] } [workspace] # indicate that this crate is not part of any workspace + +[features] +gdb = ["wasmtime/debug-builtins"] diff --git a/src/wasm_runtime/build.rs b/src/wasm_runtime/build.rs index d5d8d703..8780d60b 100644 --- a/src/wasm_runtime/build.rs +++ b/src/wasm_runtime/build.rs @@ -74,4 +74,8 @@ fn main() { if env::var_os("WIT_WORLD").is_some() { println!("cargo::rustc-cfg=component"); } + + cfg_aliases::cfg_aliases! { + gdb: { all(feature = "gdb", debug_assertions) }, + } } diff --git a/src/wasm_runtime/src/component.rs b/src/wasm_runtime/src/component.rs index c14f8cb3..14711dcf 100644 --- a/src/wasm_runtime/src/component.rs +++ b/src/wasm_runtime/src/component.rs @@ -103,6 +103,8 @@ pub extern "C" fn hyperlight_main() { let mut config = Config::new(); config.with_custom_code_memory(Some(alloc::sync::Arc::new(platform::WasmtimeCodeMemory {}))); + #[cfg(gdb)] + config.debug_info(true); let engine = Engine::new(&config).unwrap(); let linker = Linker::new(&engine); *CUR_ENGINE.lock() = Some(engine); diff --git a/src/wasm_runtime/src/module.rs b/src/wasm_runtime/src/module.rs index e3fa630d..aca5d0e1 100644 --- a/src/wasm_runtime/src/module.rs +++ b/src/wasm_runtime/src/module.rs @@ -96,6 +96,8 @@ pub fn guest_dispatch_function(function_call: FunctionCall) -> Result> { fn init_wasm_runtime() -> Result> { let mut config = Config::new(); config.with_custom_code_memory(Some(alloc::sync::Arc::new(platform::WasmtimeCodeMemory {}))); + #[cfg(gdb)] + config.debug_info(true); let engine = Engine::new(&config)?; let mut linker = Linker::new(&engine); wasip1::register_handlers(&mut linker)?; From c303c2dedcf21b1532d205b5685a953f12facaff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= Date: Mon, 29 Sep 2025 17:37:09 +0300 Subject: [PATCH 2/5] Fix build and clippy checks when gdb features is enabled on windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The toolchain paths and flags are not correctly propagated on windows. When gdb feature is enabled, wasmtime-internal-jit-debug crate tries to compile C files using cc which is not correctly set on Windows Signed-off-by: Doru Blânzeanu --- Justfile | 3 +++ src/hyperlight_wasm/build.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/Justfile b/Justfile index 7b4a226a..7e86eafa 100644 --- a/Justfile +++ b/Justfile @@ -72,6 +72,9 @@ fmt: cd src/wasm_runtime && cargo +nightly fmt -v --all cd src/hyperlight_wasm_macro && cargo +nightly fmt -v --all +export CC_x86_64_unknown_none:= if os() == "windows" { justfile_directory() / "src/wasm_runtime/guest-toolchain/clang" } else { "" } +export AR_x86_64_unknown_none:= if os() == "windows" { "llvm-ar" } else { "" } + clippy target=default-target: (check target) cargo clippy --profile={{ if target == "debug" {"dev"} else { target } }} --all-targets --all-features -- -D warnings cd src/rust_wasm_samples && cargo clippy --profile={{ if target == "debug" {"dev"} else { target } }} --all-targets --all-features -- -D warnings diff --git a/src/hyperlight_wasm/build.rs b/src/hyperlight_wasm/build.rs index 5b942123..3dc68586 100644 --- a/src/hyperlight_wasm/build.rs +++ b/src/hyperlight_wasm/build.rs @@ -134,6 +134,8 @@ fn build_wasm_runtime() -> PathBuf { .arg(&target_dir) .current_dir(&in_repo_dir) .env_clear() + // On windows when `gdb` features is enabled this is not set correctly + .env("CFLAGS_x86_64_unknown_none", "-fPIC") .envs(env_vars) .env("PATH", path_with(&toolchain_dir)) .env("HYPERLIGHT_GUEST_TOOLCHAIN_ROOT", &toolchain_dir); From a5c2e5b479b5196c42debef0fbba8078b98e6501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= Date: Tue, 21 Oct 2025 15:52:58 +0300 Subject: [PATCH 3/5] Produce warning at compile time to show wasm rt binary path for debugging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Doru Blânzeanu --- Cargo.lock | 253 ++++++++++++--------------------- Cargo.toml | 2 +- src/hyperlight_wasm/Cargo.toml | 2 +- src/hyperlight_wasm/build.rs | 13 +- src/wasm_runtime/Cargo.lock | 16 +-- src/wasm_runtime/Cargo.toml | 6 +- 6 files changed, 112 insertions(+), 180 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4320862d..98fd62ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,12 +11,6 @@ dependencies = [ "gimli", ] -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - [[package]] name = "ahash" version = "0.8.12" @@ -168,31 +162,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.32.2" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b715a6010afb9e457ca2b7c9d2b9c344baa8baed7b38dc476034c171b32575" +checksum = "107a4e9d9cab9963e04e84bb8dee0e25f2a987f9a8bad5ed054abd439caa8f8c" dependencies = [ "bindgen", "cc", "cmake", "dunce", "fs_extra", - "libloading", -] - -[[package]] -name = "backtrace" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-link", ] [[package]] @@ -207,7 +185,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -229,9 +207,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.4" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "blake3" @@ -352,9 +330,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.40" +version = "1.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" dependencies = [ "find-msvc-tools", "jobserver", @@ -457,9 +435,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cmake" @@ -852,9 +830,9 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "env_filter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" dependencies = [ "log", "regex", @@ -927,9 +905,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" [[package]] name = "flatbuffers" @@ -937,7 +915,7 @@ version = "25.9.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09b6620799e7340ebd9968d2e0708eb82cf1971e9a16821e2091b6d6e475eed5" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "rustc_version", ] @@ -1009,11 +987,11 @@ dependencies = [ [[package]] name = "gdbstub" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b686b198dfaa4109ebd0443d2841bc521e4b4b2915f1d84b3bb50332a8cdc1ae" +checksum = "72742d2b395902caf8a5d520d0dd3334ba6d1138938429200e58d5174e275f3f" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "log", "managed", @@ -1033,9 +1011,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -1049,19 +1027,19 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.7+wasi-0.2.4", + "wasip2", ] [[package]] @@ -1081,7 +1059,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2deb07a133b1520dc1a5690e9bd08950108873d7ed5de38dcc74d3b5ebffa110" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "libc", "libgit2-sys", "log", @@ -1096,9 +1074,9 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "globset" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" +checksum = "eab69130804d941f8075cfd713bf8848a2c3b3f201a9457a11e6f87e1ab62305" dependencies = [ "aho-corasick", "bstr", @@ -1139,9 +1117,9 @@ dependencies = [ [[package]] name = "half" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54c115d4f30f52c67202f079c5f9d8b49db4691f460fdb0b4c2e838261b2ba5" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", @@ -1286,8 +1264,7 @@ dependencies = [ [[package]] name = "hyperlight-common" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5230eeb4d3484f042522843abbc2989b8fe6a48418b7933b492d4394e1b95a8" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=7a266216c658331d9ff6f7315ba8c3f6a4926ad6#7a266216c658331d9ff6f7315ba8c3f6a4926ad6" dependencies = [ "anyhow", "flatbuffers", @@ -1299,8 +1276,7 @@ dependencies = [ [[package]] name = "hyperlight-component-macro" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db028cc4e57e9f47127491a2176f3a7367bc5a26ef8abd576816357d4df3e5ac" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=7a266216c658331d9ff6f7315ba8c3f6a4926ad6#7a266216c658331d9ff6f7315ba8c3f6a4926ad6" dependencies = [ "env_logger", "hyperlight-component-util", @@ -1309,14 +1285,13 @@ dependencies = [ "proc-macro2", "quote", "syn", - "wasmparser 0.239.0", + "wasmparser 0.240.0", ] [[package]] name = "hyperlight-component-util" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2946230a2d04169fe60ae13746e5973f8d810df9c76112bfcc4eeaecd5f2f8c9" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=7a266216c658331d9ff6f7315ba8c3f6a4926ad6#7a266216c658331d9ff6f7315ba8c3f6a4926ad6" dependencies = [ "itertools 0.14.0", "log", @@ -1324,17 +1299,16 @@ dependencies = [ "proc-macro2", "quote", "syn", - "wasmparser 0.239.0", + "wasmparser 0.240.0", ] [[package]] name = "hyperlight-host" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "981712e7f6d70b028576360140e210bda10e8c512d05ca6350b3d3eaeaacb27f" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=7a266216c658331d9ff6f7315ba8c3f6a4926ad6#7a266216c658331d9ff6f7315ba8c3f6a4926ad6" dependencies = [ "anyhow", - "bitflags 2.9.4", + "bitflags 2.10.0", "blake3", "cfg-if", "cfg_aliases", @@ -1554,9 +1528,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", "hashbrown 0.16.0", @@ -1564,17 +1538,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -1641,7 +1604,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] @@ -1670,7 +1633,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "333f77a20344a448f3f70664918135fddeb804e938f28a99d685bd92926e0b19" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "kvm-bindings", "libc", "vmm-sys-util", @@ -1708,12 +1671,12 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.5", + "windows-link", ] [[package]] @@ -1728,7 +1691,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "libc", "redox_syscall", ] @@ -1859,24 +1822,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - [[package]] name = "mio" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] @@ -1968,9 +1922,9 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ "num_enum_derive", "rustversion", @@ -1978,9 +1932,9 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro2", "quote", @@ -2218,7 +2172,7 @@ dependencies = [ "libc", "once_cell", "raw-cpuid", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "web-sys", "winapi", ] @@ -2274,7 +2228,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] @@ -2292,7 +2246,7 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -2321,7 +2275,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -2351,9 +2305,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.3" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -2363,9 +2317,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -2374,9 +2328,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "ring" @@ -2394,9 +2348,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "8.7.2" +version = "8.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a" +checksum = "fb44e1917075637ee8c7bcb865cf8830e3a92b5b1189e44e3a0ab5a0d5be314b" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -2405,9 +2359,9 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.7.2" +version = "8.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c" +checksum = "382499b49db77a7c19abd2a574f85ada7e9dbe125d5d1160fa5cad7c4cf71fc9" dependencies = [ "proc-macro2", "quote", @@ -2419,21 +2373,15 @@ dependencies = [ [[package]] name = "rust-embed-utils" -version = "8.7.2" +version = "8.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594" +checksum = "21fcbee55c2458836bcdbfffb6ec9ba74bbc23ca7aa6816015a3dd2c4d8fc185" dependencies = [ "globset", "sha2", "walkdir", ] -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -2455,7 +2403,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys", @@ -2464,9 +2412,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.32" +version = "0.23.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" +checksum = "751e04a496ca00bb97a5e043158d23d66b5aabf2e1d5aa2a0aaebb1aafe6f82c" dependencies = [ "aws-lc-rs", "once_cell", @@ -2478,9 +2426,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" dependencies = [ "openssl-probe", "rustls-pki-types", @@ -2580,7 +2528,7 @@ version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "core-foundation", "core-foundation-sys", "libc", @@ -2743,12 +2691,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -2780,9 +2728,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.106" +version = "2.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b" dependencies = [ "proc-macro2", "quote", @@ -2888,19 +2836,16 @@ dependencies = [ [[package]] name = "tokio" -version = "1.47.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "pin-project-lite", - "slab", "socket2", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -3035,9 +2980,9 @@ checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicode-ident" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" +checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" [[package]] name = "unicode-xid" @@ -3081,7 +3026,7 @@ version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "js-sys", "wasm-bindgen", ] @@ -3139,15 +3084,6 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" @@ -3232,7 +3168,7 @@ version = "0.236.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9b1e81f3eb254cf7404a82cee6926a4a3ccc5aad80cc3d43608a070c67aa1d7" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "hashbrown 0.15.5", "indexmap", "semver", @@ -3241,11 +3177,11 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.239.0" +version = "0.240.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9d90bb93e764f6beabf1d02028c70a2156a6583e63ac4218dd07ef733368b0" +checksum = "b722dcf61e0ea47440b53ff83ccb5df8efec57a69d150e4f24882e4eba7e24a4" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "hashbrown 0.15.5", "indexmap", "semver", @@ -3271,7 +3207,7 @@ checksum = "5b3e1fab634681494213138ea3a18e958e5ea99da13a4a01a4b870d51a41680b" dependencies = [ "addr2line", "anyhow", - "bitflags 2.9.4", + "bitflags 2.10.0", "bumpalo", "cc", "cfg-if", @@ -3492,7 +3428,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "169042d58002f16da149ab7d608b71164411abd1fc5140f48f4c200b44bb5565" dependencies = [ "anyhow", - "bitflags 2.9.4", + "bitflags 2.10.0", "heck", "indexmap", "wit-parser", @@ -3669,15 +3605,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.60.2" diff --git a/Cargo.toml b/Cargo.toml index ba2187e2..f039e826 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,4 @@ repository = "https://github.com/hyperlight-dev/hyperlight-wasm" readme = "README.md" [workspace.dependencies] -hyperlight-host = { version = "0.10.0", default-features = false, features = ["executable_heap", "init-paging"] } +hyperlight-host = { git = "https://github.com/hyperlight-dev/hyperlight", version = "0.10.0", rev = "7a266216c658331d9ff6f7315ba8c3f6a4926ad6", default-features = false, features = ["executable_heap", "init-paging"] } diff --git a/src/hyperlight_wasm/Cargo.toml b/src/hyperlight_wasm/Cargo.toml index 48781bb7..75fa4658 100644 --- a/src/hyperlight_wasm/Cargo.toml +++ b/src/hyperlight_wasm/Cargo.toml @@ -64,7 +64,7 @@ windows = { version = "0.62", features = ["Win32_System_Threading"] } page_size = "0.6.0" [dev-dependencies] -hyperlight-component-macro = { version = "0.10.0" } +hyperlight-component-macro = { git = "https://github.com/hyperlight-dev/hyperlight", rev = "7a266216c658331d9ff6f7315ba8c3f6a4926ad6", version = "0.10.0" } examples_common = { path = "../examples_common" } criterion = { version = "0.7.0", features = ["html_reports"] } crossbeam-queue = "0.3" diff --git a/src/hyperlight_wasm/build.rs b/src/hyperlight_wasm/build.rs index 3dc68586..600be6a1 100644 --- a/src/hyperlight_wasm/build.rs +++ b/src/hyperlight_wasm/build.rs @@ -156,12 +156,21 @@ fn build_wasm_runtime() -> PathBuf { .join(profile) .join("wasm_runtime"); - resource.canonicalize().unwrap_or_else(|_| { + if let Ok(path) = resource.canonicalize() { + if std::env::var("CARGO_FEATURE_GDB").is_ok() { + println!( + "cargo:warning=Wasm runtime guest binary at: {}", + path.display() + ); + } + + path + } else { panic!( "could not find wasm_runtime after building it (expected {:?})", resource ) - }) + } } fn main() -> Result<()> { diff --git a/src/wasm_runtime/Cargo.lock b/src/wasm_runtime/Cargo.lock index 6f7ccd49..ca5c59d9 100644 --- a/src/wasm_runtime/Cargo.lock +++ b/src/wasm_runtime/Cargo.lock @@ -618,8 +618,7 @@ dependencies = [ [[package]] name = "hyperlight-common" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5230eeb4d3484f042522843abbc2989b8fe6a48418b7933b492d4394e1b95a8" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=7a266216c658331d9ff6f7315ba8c3f6a4926ad6#7a266216c658331d9ff6f7315ba8c3f6a4926ad6" dependencies = [ "anyhow", "flatbuffers", @@ -645,8 +644,7 @@ dependencies = [ [[package]] name = "hyperlight-guest" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e274942ac4a0f8326652e431e493eef2e63cc0b505ae1feefa8db105b107b11" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=7a266216c658331d9ff6f7315ba8c3f6a4926ad6#7a266216c658331d9ff6f7315ba8c3f6a4926ad6" dependencies = [ "anyhow", "flatbuffers", @@ -658,12 +656,12 @@ dependencies = [ [[package]] name = "hyperlight-guest-bin" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80bc1d424b7a9ad6b74dfb90c985f25b0af6b93bc934dfb2268bca89adab9643" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=7a266216c658331d9ff6f7315ba8c3f6a4926ad6#7a266216c658331d9ff6f7315ba8c3f6a4926ad6" dependencies = [ "buddy_system_allocator", "cc", "cfg-if", + "flatbuffers", "glob", "hyperlight-common", "hyperlight-guest", @@ -675,8 +673,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf14ec1c55e993887f2d1dbecc26a89e352a1cbd4f3bb4d2fd9e3cbe0e670c5" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=7a266216c658331d9ff6f7315ba8c3f6a4926ad6#7a266216c658331d9ff6f7315ba8c3f6a4926ad6" dependencies = [ "hyperlight-common", "hyperlight-guest-tracing-macro", @@ -686,8 +683,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing-macro" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae072935591a653dfbb3d97b2a777751a9c20bece6929f72137b380c054ecae" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=7a266216c658331d9ff6f7315ba8c3f6a4926ad6#7a266216c658331d9ff6f7315ba8c3f6a4926ad6" dependencies = [ "proc-macro2", "quote", diff --git a/src/wasm_runtime/Cargo.toml b/src/wasm_runtime/Cargo.toml index 0fd77c37..ec490b26 100644 --- a/src/wasm_runtime/Cargo.toml +++ b/src/wasm_runtime/Cargo.toml @@ -11,9 +11,9 @@ doctest = false bench = false [dependencies] -hyperlight-common = { version = "0.10.0", default-features = false } -hyperlight-guest-bin = { version = "0.10.0", features = [ "printf" ] } -hyperlight-guest = { version = "0.10.0" } +hyperlight-common = { git = "https://github.com/hyperlight-dev/hyperlight", rev = "7a266216c658331d9ff6f7315ba8c3f6a4926ad6", version = "0.10.0", default-features = false } +hyperlight-guest-bin = { git = "https://github.com/hyperlight-dev/hyperlight", rev = "7a266216c658331d9ff6f7315ba8c3f6a4926ad6", version = "0.10.0", features = [ "printf" ] } +hyperlight-guest = { git = "https://github.com/hyperlight-dev/hyperlight", rev = "7a266216c658331d9ff6f7315ba8c3f6a4926ad6", version = "0.10.0" } wasmtime = { version = "36.0.2", default-features = false, features = [ "runtime", "custom-virtual-memory", "custom-native-signals", "component-model" ] } hyperlight-wasm-macro = { path = "../hyperlight_wasm_macro" } spin = "0.10.0" From d6832dee5edaaef05242982b056e3187d6cc4eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= Date: Tue, 21 Oct 2025 16:21:08 +0300 Subject: [PATCH 4/5] Add documentation for native wasm modules debugging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Doru Blânzeanu --- docs/wasm-modules-debugging.md | 90 ++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 docs/wasm-modules-debugging.md diff --git a/docs/wasm-modules-debugging.md b/docs/wasm-modules-debugging.md new file mode 100644 index 00000000..79e25674 --- /dev/null +++ b/docs/wasm-modules-debugging.md @@ -0,0 +1,90 @@ +# Debugging WebAssembly Modules + +This guide provides an overview of the methods and tools available for debugging native Wasm modules in the Hyperlight-Wasm environment. Effective debugging is crucial for identifying and resolving issues in Wasm modules, ensuring they function correctly within the host application. + +## Building with Debug Information + +To facilitate debugging, it is recommended to compile your Wasm modules with debug information included. This can be achieved by using the appropriate flags during the compilation process. +For example, when using `wasi-sdk/clang`, you can include the `-g` flag to generate debug information and `-O0` to disable optimizations. +You can find examples of native Wasm modules in the repository under the `rust_wasm_samples`, `wasm_samples` and `component_sample` directories. + +Next, ensure that the pre-compiled Wasm modules are built with debug information as well. To do this, you can use the `hyperlight-wasm-aot` tool with the `--features gdb` flag: + +```bash +cargo run --features gdb -p hyperlight-wasm-aot compile input.wasm output.aot +``` + + +## Example of debugging a Wasm Module +We have a simple example of debugging a Wasm module in the [examples/guest-debugging](../src/hyperlight_wasm/examples/guest-debugging) directory. + +This example demonstrates how to configure a Hyperlight Sandbox to enable debugging support for a Wasm module. + +When running the example, it starts a GDB server on `localhost:8080`, allowing you to connect your debugger to this address. +It hangs waiting for a debugger to attach before proceeding with the execution. +You can use either GDB or LLDB to attach to the running process. +You can find a sample `launch.json` configuration for Visual Studio Code that sets up remote debugging for the Wasm module using both GDB and LLDB at [VSCode launch.json Configuration](#vscode-launchjson-configuration). + +The json configuration asks for the path to the guest binary to debug, which you see printed as a `cargo:warning` when `hyperlight-wasm`, with `gdb` feature enabled, is built. +After you attach, you can set breakpoints, step through the code, and inspect variables in your wasm module as you would with any native application. + +**NOTE**: The debugger stops at the entry point of the guest binary, which is the `hyperlight-wasm` runtime in this case, so you may need to set additional breakpoints in your Wasm module code to effectively debug it. + +### Visual Studio Code `launch.json` Configuration + +```json + +{ + "inputs": [ + { + "id": "program", + "type": "promptString", + "default": "x64/debug/wasm_runtime", + "description": "Path to the program to debug" + }, + ], + "configurations": [ + { + "name": "Remote GDB attach", + "type": "cppdbg", + "request": "launch", + "program": "${input:program}", + "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 + } + ] + }, + { + "name": "Remote LLDB attach", + "type": "lldb", + "request": "launch", + "targetCreateCommands": [ + "target create ${input:program}" + ], + "processCreateCommands": [ + "gdb-remote localhost:8080" + ] + }, + ] +} +``` From a18e5edff8a62d9d6a2692571ac4f7df6a110967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Doru=20Bl=C3=A2nzeanu?= Date: Tue, 28 Oct 2025 21:25:20 +0200 Subject: [PATCH 5/5] Make hyperlight-wasm-aot take --debug command argument to enable debug info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Doru Blânzeanu --- docs/wasm-modules-debugging.md | 4 +-- src/hyperlight_wasm_aot/src/main.rs | 47 +++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/docs/wasm-modules-debugging.md b/docs/wasm-modules-debugging.md index 79e25674..fbe2e8be 100644 --- a/docs/wasm-modules-debugging.md +++ b/docs/wasm-modules-debugging.md @@ -8,10 +8,10 @@ To facilitate debugging, it is recommended to compile your Wasm modules with deb For example, when using `wasi-sdk/clang`, you can include the `-g` flag to generate debug information and `-O0` to disable optimizations. You can find examples of native Wasm modules in the repository under the `rust_wasm_samples`, `wasm_samples` and `component_sample` directories. -Next, ensure that the pre-compiled Wasm modules are built with debug information as well. To do this, you can use the `hyperlight-wasm-aot` tool with the `--features gdb` flag: +Next, ensure that the pre-compiled Wasm modules are built with debug information as well. To do this, you can use the `hyperlight-wasm-aot` tool with the `--debug` command argument: ```bash -cargo run --features gdb -p hyperlight-wasm-aot compile input.wasm output.aot +cargo run -p hyperlight-wasm-aot compile --debug input.wasm output.aot ``` diff --git a/src/hyperlight_wasm_aot/src/main.rs b/src/hyperlight_wasm_aot/src/main.rs index 93578e87..835e919e 100644 --- a/src/hyperlight_wasm_aot/src/main.rs +++ b/src/hyperlight_wasm_aot/src/main.rs @@ -19,9 +19,7 @@ use std::path::Path; use cargo_metadata::{MetadataCommand, Package}; use cargo_util_schemas::manifest::PackageName; use clap::{Arg, Command}; -#[cfg(feature = "gdb")] -use wasmtime::OptLevel; -use wasmtime::{Config, Engine, Module, Precompiled}; +use wasmtime::{Config, Engine, Module, OptLevel, Precompiled}; fn main() { let hyperlight_wasm_aot_version = env!("CARGO_PKG_VERSION"); @@ -49,6 +47,13 @@ fn main() { .required(false) .long("component") .action(clap::ArgAction::SetTrue), + ) + .arg( + Arg::new("debug") + .help("Precompile with debug and disable optimizations") + .required(false) + .long("debug") + .action(clap::ArgAction::SetTrue), ), ) .subcommand( @@ -59,6 +64,13 @@ fn main() { .help("The aot compiled file to check") .required(true) .index(1), + ) + .arg( + Arg::new("debug") + .help("Specifies if the module has been compiled with debug support") + .required(false) + .long("debug") + .action(clap::ArgAction::SetTrue), ), ) .get_matches(); @@ -75,8 +87,16 @@ fn main() { path.to_str().unwrap().to_string().clone() } }; - println!("Aot Compiling {} to {}", infile, outfile); - let config = get_config(); + let debug = args.get_flag("debug"); + if debug { + println!( + "Aot Compiling {} to {} with debug info and optimizations off", + infile, outfile + ); + } else { + println!("Aot Compiling {} to {}", infile, outfile); + } + let config = get_config(debug); let engine = Engine::new(&config).unwrap(); let bytes = std::fs::read(infile).unwrap(); let serialized = if args.get_flag("component") { @@ -99,11 +119,19 @@ fn main() { let args = matches .subcommand_matches("check-wasmtime-version") .unwrap(); + let debug = args.get_flag("debug"); let file = args.get_one::("file").unwrap(); - println!("Checking Wasmtime version used to compile file: {}", file); + if debug { + println!( + "Checking Wasmtime version used to compile debug info enabled file: {}", + file + ); + } else { + println!("Checking Wasmtime version used to compile file: {}", file); + } // load the file into wasmtime, check that it is aot compiled and extract the version of wasmtime used to compile it from its metadata let bytes = std::fs::read(file).unwrap(); - let config = get_config(); + let config = get_config(debug); let engine = Engine::new(&config).unwrap(); match Engine::detect_precompiled(&bytes) { Some(pre_compiled) => { @@ -153,13 +181,12 @@ fn main() { } /// Returns a new `Config` for the Wasmtime engine with additional settings for AOT compilation. -fn get_config() -> Config { +fn get_config(debug: bool) -> Config { let mut config = Config::new(); config.target("x86_64-unknown-none").unwrap(); // Enable the default features for the Wasmtime engine. - #[cfg(feature = "gdb")] - { + if debug { config.debug_info(true); config.cranelift_opt_level(OptLevel::None); }