[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