[Lldb-commits] [lldb] 32e83ea - [lldb] Pass Wasm runtime-args before the port argument (#220700)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Sep 2 14:50:08 PDT 2026
Author: Jonas Devlieghere
Date: 2026-09-02T14:50:04-07:00
New Revision: 32e83eafa73dbdd8edd113de787e2819ea049357
URL: https://github.com/llvm/llvm-project/commit/32e83eafa73dbdd8edd113de787e2819ea049357
DIFF: https://github.com/llvm/llvm-project/commit/32e83eafa73dbdd8edd113de787e2819ea049357.diff
LOG: [lldb] Pass Wasm runtime-args before the port argument (#220700)
A runtime that dispatches on a leading subcommand, such as WasmKit's
`wasmkit run`, could not be driven directly: runtime-args landed after
the port argument, so the subcommand did too and the runtime rejected
it. Naming the subcommand required a wrapper script. Move runtime-args
ahead of the port argument so the setting can carry it.
Extract the command line assembly into PlatformWasm::MakeRuntimeCommand
so the ordering is covered by unit tests, and clarify that port-arg has
to carry its value in the same argument.
Added:
lldb/unittests/Platform/PlatformWasmTest.cpp
Modified:
lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp
lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.h
lldb/source/Plugins/Platform/WebAssembly/PlatformWasmProperties.td
lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
lldb/source/Plugins/Process/wasm/ProcessWasm.h
lldb/unittests/Platform/CMakeLists.txt
llvm/docs/ReleaseNotes.md
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp
index eb1cdac11c146..2dee06e414c5b 100644
--- a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp
+++ b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp
@@ -146,6 +146,36 @@ lldb::ProcessSP PlatformWasm::Attach(ProcessAttachInfo &attach_info,
return nullptr;
}
+Args PlatformWasm::MakeRuntimeCommand(llvm::StringRef runtime_path,
+ const Args &runtime_args,
+ llvm::StringRef port_arg, uint16_t port,
+ llvm::StringRef env_arg,
+ const Environment &env,
+ llvm::StringRef module_path,
+ const Args &inferior_args) {
+ Args args({runtime_path});
+ args.AppendArguments(runtime_args);
+ args.AppendArgument(llvm::formatv("{0}{1}", port_arg, port).str());
+
+ if (!env_arg.empty())
+ for (const auto &kv : env)
+ args.AppendArgument(
+ llvm::formatv("{0}{1}", env_arg, Environment::compose(kv)).str());
+
+ // The runtime resolves the module as a host path, while arg0 is the name the
+ // platform reports for the executable and need not resolve here.
+ Args module_args = inferior_args;
+ if (!module_path.empty()) {
+ if (module_args.GetArgumentCount() > 0)
+ module_args.ReplaceArgumentAtIndex(0, module_path);
+ else
+ module_args.AppendArgument(module_path);
+ }
+ args.AppendArguments(module_args);
+
+ return args;
+}
+
lldb::ProcessSP PlatformWasm::DebugProcess(ProcessLaunchInfo &launch_info,
Debugger &debugger, Target &target,
Status &error) {
@@ -173,30 +203,14 @@ lldb::ProcessSP PlatformWasm::DebugProcess(ProcessLaunchInfo &launch_info,
}
uint16_t port = *expected_port;
- Args args({runtime.GetPath(),
- llvm::formatv("{0}{1}", properties.GetPortArg(), port).str()});
- args.AppendArguments(properties.GetRuntimeArgs());
-
- // Forward the inferior's environment into the WASI runtime. How arguments are
- // passed is configurable. When not configured, no environment is passed.
- if (llvm::StringRef env_arg = properties.GetEnvArg(); !env_arg.empty())
- for (const auto &kv : launch_info.GetEnvironment())
- args.AppendArgument(
- llvm::formatv("{0}{1}", env_arg, Environment::compose(kv)).str());
+ std::string module_path;
+ if (ModuleSP exe_module_sp = target.GetExecutableModule())
+ module_path = exe_module_sp->GetFileSpec().GetPath();
- // The runtime is handed the module to run as a path on this host. A launch
- // takes its executable from the name the module goes by on the platform,
- // which for a module reported by a stub is a name of the stub's choosing
- // rather than a path that resolves here, so run the file the target has.
- Args inferior_args = launch_info.GetArguments();
- if (ModuleSP exe_module_sp = target.GetExecutableModule()) {
- const std::string exe_path = exe_module_sp->GetFileSpec().GetPath();
- if (inferior_args.GetArgumentCount() > 0)
- inferior_args.ReplaceArgumentAtIndex(0, exe_path);
- else
- inferior_args.AppendArgument(exe_path);
- }
- args.AppendArguments(inferior_args);
+ Args args = MakeRuntimeCommand(
+ runtime.GetPath(), properties.GetRuntimeArgs(), properties.GetPortArg(),
+ port, properties.GetEnvArg(), launch_info.GetEnvironment(), module_path,
+ launch_info.GetArguments());
launch_info.SetArguments(args, true);
launch_info.SetLaunchInSeparateProcessGroup(true);
diff --git a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.h b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.h
index e752b8bae9840..0fba3c09df5bd 100644
--- a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.h
+++ b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.h
@@ -43,6 +43,16 @@ class PlatformWasm : public RemoteAwarePlatform {
lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
Target *target, Status &status) override;
+ /// Assemble the command line that launches the runtime on \p module_path,
+ /// serving its GDB remote stub on \p port. Extra \p runtime_args precede the
+ /// port argument, so they can carry a subcommand the runtime expects first,
+ /// such as WasmKit's `run`. An empty \p env_arg forwards no environment.
+ static Args
+ MakeRuntimeCommand(llvm::StringRef runtime_path, const Args &runtime_args,
+ llvm::StringRef port_arg, uint16_t port,
+ llvm::StringRef env_arg, const Environment &env,
+ llvm::StringRef module_path, const Args &inferior_args);
+
Status ConnectRemote(Args &args) override;
void CalculateTrapHandlerSymbolNames() override {}
diff --git a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasmProperties.td b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasmProperties.td
index 1fe27d9caf44d..21b4985524d1b 100644
--- a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasmProperties.td
+++ b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasmProperties.td
@@ -12,8 +12,9 @@ let Definition = "platformwasm", Path = "platform.plugin.wasm" in {
DefaultStringValue<"">,
Desc<"Argument to the WebAssembly runtime to specify the "
"GDB remote port. The port number chosen by LLDB will be "
- "concatenated to this argument. For example: "
- "`-g=127.0.0.1:` or `--debugger-port `.">;
+ "concatenated to this argument, which therefore has to "
+ "carry its value in the same argument. For example: "
+ "`-g=127.0.0.1:` or `--debugger-port=`.">;
def EnvArg : Property<"env-arg", "String">,
Global,
DefaultStringValue<"">,
@@ -26,6 +27,8 @@ let Definition = "platformwasm", Path = "platform.plugin.wasm" in {
Global,
DefaultStringValue<"">,
Desc<"Extra arguments to pass to the WebAssembly runtime. "
+ "They precede the port argument, so a runtime that "
+ "dispatches on a leading subcommand names it here. "
"For the argument that specifies the GDB remote port, "
"use port-arg instead.">;
}
diff --git a/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp b/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
index 3e2bf05e00a0c..87c3a32f0cd5d 100644
--- a/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
+++ b/lldb/source/Plugins/Process/wasm/ProcessWasm.cpp
@@ -48,8 +48,6 @@ void ProcessWasm::DebuggerInitialize(Debugger &debugger) {
llvm::StringRef ProcessWasm::GetPluginName() { return GetPluginNameStatic(); }
-llvm::StringRef ProcessWasm::GetPluginNameStatic() { return "wasm"; }
-
llvm::StringRef ProcessWasm::GetPluginDescriptionStatic() {
return "GDB Remote protocol based WebAssembly debugging plug-in.";
}
diff --git a/lldb/source/Plugins/Process/wasm/ProcessWasm.h b/lldb/source/Plugins/Process/wasm/ProcessWasm.h
index cffff2fa54093..d44c1fc6defd0 100644
--- a/lldb/source/Plugins/Process/wasm/ProcessWasm.h
+++ b/lldb/source/Plugins/Process/wasm/ProcessWasm.h
@@ -32,7 +32,7 @@ class ProcessWasm : public process_gdb_remote::ProcessGDBRemote {
static void DebuggerInitialize(Debugger &debugger);
static void Terminate();
- static llvm::StringRef GetPluginNameStatic();
+ static llvm::StringRef GetPluginNameStatic() { return "wasm"; }
static llvm::StringRef GetPluginDescriptionStatic();
llvm::StringRef GetPluginName() override;
diff --git a/lldb/unittests/Platform/CMakeLists.txt b/lldb/unittests/Platform/CMakeLists.txt
index b3c87b33527bd..693faa07e53f8 100644
--- a/lldb/unittests/Platform/CMakeLists.txt
+++ b/lldb/unittests/Platform/CMakeLists.txt
@@ -5,6 +5,7 @@ add_lldb_unittest(LLDBPlatformTests
PlatformMacOSXTest.cpp
PlatformSiginfoTest.cpp
PlatformTest.cpp
+ PlatformWasmTest.cpp
LINK_COMPONENTS
Support
@@ -13,6 +14,7 @@ add_lldb_unittest(LLDBPlatformTests
lldbPluginPlatformLinux
lldbPluginPlatformMacOSX
lldbPluginPlatformNetBSD
+ lldbPluginPlatformWasm
lldbUtilityHelpers
LLVMTestingSupport
)
diff --git a/lldb/unittests/Platform/PlatformWasmTest.cpp b/lldb/unittests/Platform/PlatformWasmTest.cpp
new file mode 100644
index 0000000000000..f24e4e66c8671
--- /dev/null
+++ b/lldb/unittests/Platform/PlatformWasmTest.cpp
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Platform/WebAssembly/PlatformWasm.h"
+#include "lldb/Utility/Args.h"
+#include "lldb/Utility/Environment.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+using ::testing::ElementsAre;
+
+static std::vector<std::string> GetArgStrings(const Args &args) {
+ std::vector<std::string> result;
+ for (const Args::ArgEntry &entry : args)
+ result.push_back(entry.c_str());
+ return result;
+}
+
+TEST(PlatformWasmTest, MakeRuntimeCommand) {
+ Args args = PlatformWasm::MakeRuntimeCommand(
+ "/bin/runtime", Args(), "-g=127.0.0.1:", 1234, /*env_arg=*/"",
+ Environment(), "/tmp/module.wasm", Args());
+
+ EXPECT_THAT(
+ GetArgStrings(args),
+ ElementsAre("/bin/runtime", "-g=127.0.0.1:1234", "/tmp/module.wasm"));
+}
+
+TEST(PlatformWasmTest, MakeRuntimeCommandRuntimeArgsPrecedePort) {
+ // A runtime dispatching on a leading subcommand names it through
+ // runtime-args, which is only usable if those come before the port.
+ Args runtime_args;
+ runtime_args.AppendArgument("run");
+
+ Args args = PlatformWasm::MakeRuntimeCommand(
+ "/bin/runtime", runtime_args, "--debugger-port=", 1234, /*env_arg=*/"",
+ Environment(), "/tmp/module.wasm", Args());
+
+ EXPECT_THAT(GetArgStrings(args),
+ ElementsAre("/bin/runtime", "run", "--debugger-port=1234",
+ "/tmp/module.wasm"));
+}
+
+TEST(PlatformWasmTest, MakeRuntimeCommandForwardsEnvironment) {
+ Environment env;
+ env["KEY"] = "value";
+
+ Args args = PlatformWasm::MakeRuntimeCommand("/bin/runtime", Args(),
+ "-g=", 1234, "--env=", env,
+ "/tmp/module.wasm", Args());
+
+ EXPECT_THAT(GetArgStrings(args),
+ ElementsAre("/bin/runtime", "-g=1234", "--env=KEY=value",
+ "/tmp/module.wasm"));
+}
+
+TEST(PlatformWasmTest, MakeRuntimeCommandWithoutEnvArgDropsEnvironment) {
+ Environment env;
+ env["KEY"] = "value";
+
+ Args args = PlatformWasm::MakeRuntimeCommand(
+ "/bin/runtime", Args(), "-g=", 1234,
+ /*env_arg=*/"", env, "/tmp/module.wasm", Args());
+
+ EXPECT_THAT(GetArgStrings(args),
+ ElementsAre("/bin/runtime", "-g=1234", "/tmp/module.wasm"));
+}
+
+TEST(PlatformWasmTest, MakeRuntimeCommandModulePathReplacesArgZero) {
+ Args inferior_args;
+ inferior_args.AppendArgument("module.wasm");
+ inferior_args.AppendArgument("--flag");
+
+ Args args = PlatformWasm::MakeRuntimeCommand(
+ "/bin/runtime", Args(), "-g=", 1234, /*env_arg=*/"", Environment(),
+ "/tmp/module.wasm", inferior_args);
+
+ EXPECT_THAT(GetArgStrings(args), ElementsAre("/bin/runtime", "-g=1234",
+ "/tmp/module.wasm", "--flag"));
+}
+
+TEST(PlatformWasmTest, MakeRuntimeCommandWithoutModulePath) {
+ Args inferior_args;
+ inferior_args.AppendArgument("module.wasm");
+
+ Args args = PlatformWasm::MakeRuntimeCommand(
+ "/bin/runtime", Args(), "-g=", 1234, /*env_arg=*/"", Environment(),
+ /*module_path=*/"", inferior_args);
+
+ EXPECT_THAT(GetArgStrings(args),
+ ElementsAre("/bin/runtime", "-g=1234", "module.wasm"));
+}
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 9b858caadb6c3..ce9c48723bff1 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -248,6 +248,11 @@ Makes programs 10x faster by doing Special New Thing.
### Changes to LLDB
+* `platform.plugin.wasm.runtime-args` now precede the port argument on the Wasm
+ runtime's command line instead of following it. A runtime that dispatches on a
+ leading subcommand can therefore name that subcommand through this setting,
+ rather than needing a wrapper script.
+
#### SBAPI
* A [bug](https://github.com/llvm/llvm-project/issues/211787) involving SBValues
More information about the lldb-commits
mailing list