Debugging and Testing LLDB with WebAssembly#
LLDB debugs WebAssembly through a standalone Wasm runtime. The runtime executes
the module and serves a GDB remote stub. LLDBās wasm platform launches the
runtime, picks a free TCP port and connects to the stub on it. The LLDB API test
suite uses the same setup to compile its test programs to WebAssembly and run
them.
This page covers configuring LLDB and the wasm platform. For building a
runtime, see the runtimeās own documentation.
Prerequisites#
A wasi-sdk release, which provides the WASI sysroot, the wasm
compiler-rtbuiltins and awasm-ld.A Wasm runtime that serves a GDB remote stub. WAMR and WasmKit are shown below.
Choosing a compiler#
Test programs are built for wasm32-wasip1, which both the wasi-sdk clang and
an upstream in-tree clang can target. LLDB_TEST_COMPILER picks one. It
defaults to the in-tree clang whenever clang is part of the build.
Prefer the in-tree clang, since it matches the LLDB under test and exercises in-tree DWARF and codegen changes. Unlike the wasi-sdk clang, it needs two things supplied:
wasm-ld. Enable LLD in the build and it lands next toclang, where the driver looks beforePATH. Without LLD, symlink the wasi-sdkāswasm-ldinto that same directory.The wasm
compiler-rtbuiltins, throughLLDB_TEST_RESOURCE_DIRpointed at the wasi-sdkās clang resource directory.
Both compilers need the WASI sysroot, passed as LLDB_TEST_SYSROOT.
Configuring the platform#
The wasm platform is selected with --platform-name wasm. The global
platform.plugin.wasm settings runtime-path,
port-arg, env-arg and runtime-args describe how to invoke the runtime.
env-arg is optional. Set it to forward the launch environment
(target.env-vars, process launch -E).
LLDB assembles the runtimeās command line as:
<runtime-path> <runtime-args...> <port-arg><port> <env-arg><key=value>... <module> <inferior-args...>
runtime-args precedes the port argument, so a runtime that dispatches on a
leading subcommand names that subcommand there. port-arg has to carry the port
in a single argument, because LLDB concatenates the two. env-arg is repeated
once per environment variable, for example --env=A=1 --env=B=2.
A runtimeās diagnostics share the inferiorās standard error, so a verbose runtime breaks tests that match program output. Use its quietest logging.
Most of these values begin with a dash, so the settings set examples below
pass -- first to stop the command from reading them as its own options.
Example runtimes#
WAMR#
WAMRās iwasm takes
the debug server address as host:port. Its default heap and stack are small
enough that some tests trap, so raise them.
settings set -- platform.plugin.wasm.runtime-path /path/to/iwasm
settings set -- platform.plugin.wasm.runtime-args --heap-size=1048576 --stack-size=1048576 -v=0
settings set -- platform.plugin.wasm.port-arg -g=127.0.0.1:
settings set -- platform.plugin.wasm.env-arg --env=
WasmKit#
WasmKitās CLI takes a bare port number
and defaults to quiet, so run is all it needs beyond the port. That subcommand
has to come first, which is what runtime-args is for.
settings set -- platform.plugin.wasm.runtime-path /path/to/wasmkit-cli
settings set -- platform.plugin.wasm.runtime-args run
settings set -- platform.plugin.wasm.port-arg --debugger-port=
settings set -- platform.plugin.wasm.env-arg --env=
Note
WasmKitās debugger support is behind the WasmDebuggingSupport package trait.
A CLI built without it rejects --debugger-port as an unknown option. Build
with
swift build -c release --product wasmkit-cli --traits WasmDebuggingSupport,
adding whichever other traits you need.
Running the test suite#
Point the test suite at the sysroot and the resource directory, and pass the
target and platform configuration through LLDB_TEST_USER_ARGS:
$ cmake -G Ninja \
-DLLDB_TEST_SYSROOT=/path/to/wasi-sdk/share/wasi-sysroot \
-DLLDB_TEST_RESOURCE_DIR=/path/to/wasi-sdk/lib/clang/<version> \
-DLLDB_TEST_USER_ARGS="--triple;wasm32-wasip1;--platform-name;wasm;--setting;platform.plugin.wasm.runtime-path=/path/to/iwasm;--setting;platform.plugin.wasm.port-arg=-g=127.0.0.1:;--setting;platform.plugin.wasm.env-arg=--env=;--setting;platform.plugin.wasm.runtime-args=--heap-size=1048576 --stack-size=1048576 -v=0" \
<other options>
$ ninja check-lldb-api
lldb-dotest takes the same configuration as command line arguments, which is
easier if you keep the build configured for the host. There -C, --sysroot
and --resource-dir replace the three CMake variables. Also pass a separate
--build-dir so Wasm and host inferiors do not share an output directory.
The triple, platform and runtime settings reach only the API tests, so
check-lldb-unit is unaffected and check-lldb-shell still builds for the
host. LLDB_TEST_SYSROOT is the exception, since the shell tests also read it
as their host sysroot. Keep the Wasm sysroot out of a build that runs them.