[lldb] Add PlatformWebInspectorWasm#188751
Conversation
Add a new PlatformWebInspectorWasm, which is a Wasm platform that automatically connects to the WebInspector platform server.
|
@llvm/pr-subscribers-lldb Author: Jonas Devlieghere (JDevlieghere) ChangesAdd a new PlatformWebInspectorWasm, which is a Wasm platform that automatically connects to the WebInspector platform server. 5 Files Affected:
diff --git a/lldb/source/Plugins/Platform/WebAssembly/CMakeLists.txt b/lldb/source/Plugins/Platform/WebAssembly/CMakeLists.txt
index e049937dffd47..3149189cbe32c 100644
--- a/lldb/source/Plugins/Platform/WebAssembly/CMakeLists.txt
+++ b/lldb/source/Plugins/Platform/WebAssembly/CMakeLists.txt
@@ -9,6 +9,7 @@ lldb_tablegen(PlatformWasmPropertiesEnum.inc -gen-lldb-property-enum-defs
add_lldb_library(lldbPluginPlatformWasm PLUGIN
PlatformWasm.cpp
PlatformWasmRemoteGDBServer.cpp
+ PlatformWebInspectorWasm.cpp
LINK_LIBS
lldbCore
diff --git a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp
index bcc71f83a017d..c9af2551281e9 100644
--- a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp
+++ b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp
@@ -8,6 +8,7 @@
#include "Plugins/Platform/WebAssembly/PlatformWasm.h"
#include "Plugins/Platform/WebAssembly/PlatformWasmRemoteGDBServer.h"
+#include "Plugins/Platform/WebAssembly/PlatformWebInspectorWasm.h"
#include "Plugins/Process/wasm/ProcessWasm.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/FileSystem.h"
@@ -71,6 +72,7 @@ llvm::StringRef PlatformWasm::GetPluginDescriptionStatic() {
}
void PlatformWasm::Initialize() {
+ PlatformWebInspectorWasm::Initialize();
PluginManager::RegisterPlugin(
GetPluginNameStatic(), GetPluginDescriptionStatic(),
PlatformWasm::CreateInstance, PlatformWasm::DebuggerInitialize);
@@ -78,6 +80,7 @@ void PlatformWasm::Initialize() {
void PlatformWasm::Terminate() {
PluginManager::UnregisterPlugin(PlatformWasm::CreateInstance);
+ PlatformWebInspectorWasm::Terminate();
}
void PlatformWasm::DebuggerInitialize(Debugger &debugger) {
@@ -113,17 +116,20 @@ PlatformSP PlatformWasm::CreateInstance(bool force, const ArchSpec *arch) {
return create ? PlatformSP(new PlatformWasm()) : PlatformSP();
}
+llvm::Expected<uint16_t> PlatformWasm::FindFreeTCPPort() {
+ TCPSocket sock(true);
+ Status status = sock.Listen("localhost:0", /*backlog=*/5);
+ if (status.Fail())
+ return status.takeError();
+ return sock.GetLocalPortNumber();
+}
+
std::vector<ArchSpec>
PlatformWasm::GetSupportedArchitectures(const ArchSpec &process_host_arch) {
return {ArchSpec("wasm32-unknown-unknown-wasm"),
ArchSpec("wasm64-unknown-unknown-wasm")};
}
-static auto get_arg_range(const Args &args) {
- return llvm::make_range(args.GetArgumentArrayRef().begin(),
- args.GetArgumentArrayRef().end());
-}
-
lldb::ProcessSP PlatformWasm::Attach(ProcessAttachInfo &attach_info,
Debugger &debugger, Target *target,
Status &status) {
@@ -155,18 +161,12 @@ lldb::ProcessSP PlatformWasm::DebugProcess(ProcessLaunchInfo &launch_info,
return nullptr;
}
- uint16_t port = 0;
- {
- // Get the next available port by binding a socket to port 0.
- TCPSocket listen_socket(true);
- error = listen_socket.Listen("localhost:0", /*backlog=*/5);
- if (error.Fail())
- return nullptr;
- port = listen_socket.GetLocalPortNumber();
- }
-
- if (error.Fail())
+ llvm::Expected<uint16_t> expected_port = FindFreeTCPPort();
+ if (!expected_port) {
+ error = Status::FromError(expected_port.takeError());
return nullptr;
+ }
+ uint16_t port = *expected_port;
Args args({runtime.GetPath(),
llvm::formatv("{0}{1}", properties.GetPortArg(), port).str()});
@@ -192,7 +192,7 @@ lldb::ProcessSP PlatformWasm::DebugProcess(ProcessLaunchInfo &launch_info,
llvm::Error Err = launch_info.SetUpPtyRedirection();
LLDB_LOG_ERROR(log, std::move(Err), "SetUpPtyRedirection failed: {0}");
- LLDB_LOG(log, "{0}", get_arg_range(launch_info.GetArguments()));
+ LLDB_LOG(log, "{0}", GetArgRange(launch_info.GetArguments()));
error = Host::LaunchProcess(launch_info);
if (error.Fail())
return nullptr;
diff --git a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.h b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.h
index 5744ca7d0ca22..e752b8bae9840 100644
--- a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.h
+++ b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.h
@@ -55,11 +55,20 @@ class PlatformWasm : public RemoteAwarePlatform {
arch, addr, length, prot, flags, fd, offset);
}
+protected:
+ /// Find a free TCP port by binding to port 0.
+ static llvm::Expected<uint16_t> FindFreeTCPPort();
+
+ static auto GetArgRange(const Args &args) {
+ return llvm::make_range(args.GetArgumentArrayRef().begin(),
+ args.GetArgumentArrayRef().end());
+ }
+
+ PlatformWasm() : RemoteAwarePlatform(/*is_host=*/false) {}
+
private:
static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
static void DebuggerInitialize(Debugger &debugger);
-
- PlatformWasm() : RemoteAwarePlatform(/*is_host=*/false) {}
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/Platform/WebAssembly/PlatformWebInspectorWasm.cpp b/lldb/source/Plugins/Platform/WebAssembly/PlatformWebInspectorWasm.cpp
new file mode 100644
index 0000000000000..fc60a98f46862
--- /dev/null
+++ b/lldb/source/Plugins/Platform/WebAssembly/PlatformWebInspectorWasm.cpp
@@ -0,0 +1,177 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "PlatformWebInspectorWasm.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/ErrorExtras.h"
+
+#include <chrono>
+#include <csignal>
+#include <thread>
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(PlatformWebInspectorWasm)
+
+static constexpr llvm::StringLiteral kServerBinary =
+ "/System/Cryptexes/App/usr/libexec/webinspector-wasm-lldb-platform";
+static constexpr uint8_t kConnectAttempts = 5;
+static constexpr auto kConnectDelay = std::chrono::milliseconds(100);
+
+llvm::StringRef PlatformWebInspectorWasm::GetPluginDescriptionStatic() {
+ return "Platform for debugging Wasm via WebInspector";
+}
+
+void PlatformWebInspectorWasm::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ PlatformWebInspectorWasm::CreateInstance);
+}
+
+void PlatformWebInspectorWasm::Terminate() {
+ PluginManager::UnregisterPlugin(PlatformWebInspectorWasm::CreateInstance);
+}
+
+PlatformSP PlatformWebInspectorWasm::CreateInstance(bool force,
+ const ArchSpec *arch) {
+ Log *log = GetLog(LLDBLog::Platform);
+ LLDB_LOG(log, "force = {0}, arch = ({1}, {2})", force,
+ arch ? arch->GetArchitectureName() : "<null>",
+ arch ? arch->GetTriple().getTriple() : "<null>");
+ return force ? PlatformSP(new PlatformWebInspectorWasm()) : PlatformSP();
+}
+
+PlatformWebInspectorWasm::~PlatformWebInspectorWasm() {
+ if (m_server_pid != LLDB_INVALID_PROCESS_ID)
+ Host::Kill(m_server_pid, SIGTERM);
+}
+
+llvm::Error PlatformWebInspectorWasm::LaunchPlatformServer() {
+ Log *log = GetLog(LLDBLog::Platform);
+
+ if (!FileSystem::Instance().Exists(FileSpec(kServerBinary)))
+ return llvm::createStringErrorV("platform binary not found: {0}",
+ kServerBinary);
+
+ // Find two free TCP ports.
+ llvm::Expected<uint16_t> expected_platform_port = FindFreeTCPPort();
+ if (!expected_platform_port)
+ return expected_platform_port.takeError();
+ uint16_t platform_port = *expected_platform_port;
+
+ llvm::Expected<uint16_t> expected_debugserver_port = FindFreeTCPPort();
+ if (!expected_debugserver_port)
+ return expected_debugserver_port.takeError();
+ uint16_t debugserver_port = *expected_debugserver_port;
+
+ ProcessLaunchInfo launch_info;
+ launch_info.SetExecutableFile(FileSpec(kServerBinary),
+ /*add_exe_file_as_first_arg=*/true);
+ Args args;
+ args.AppendArgument(kServerBinary);
+ args.AppendArgument("--platform");
+ args.AppendArgument(llvm::utostr(platform_port));
+ args.AppendArgument("--debugserver");
+ args.AppendArgument(llvm::utostr(debugserver_port));
+ launch_info.SetArguments(args, /*first_arg_is_executable=*/true);
+ launch_info.SetLaunchInSeparateProcessGroup(true);
+ launch_info.GetFlags().Clear(eLaunchFlagDebug);
+
+ launch_info.SetMonitorProcessCallback(
+ [log](lldb::pid_t pid, int signal, int status) {
+ LLDB_LOG(log,
+ "Platform exited: pid = {0}, signal = "
+ "{1}, status = {2}",
+ pid, signal, status);
+ });
+
+ LLDB_LOG(log, "{0}", GetArgRange(launch_info.GetArguments()));
+
+ Status status = Host::LaunchProcess(launch_info);
+ if (status.Fail())
+ return status.takeError();
+
+ m_server_pid = launch_info.GetProcessID();
+ LLDB_LOG(log, "Platform launched: pid = {0}", m_server_pid);
+
+ Args connect_args;
+ connect_args.AppendArgument(
+ llvm::formatv("connect://localhost:{0}", platform_port).str());
+
+ // The platform may need some time to bind a socket to the requested port.
+ for (uint8_t attempt = 0; attempt < kConnectAttempts; attempt++) {
+ status = PlatformWasm::ConnectRemote(connect_args);
+ if (status.Success())
+ return llvm::Error::success();
+
+ LLDB_LOG(
+ log,
+ "[{0}/{1}] platform not yet listening on port {2}: trying again in {3}",
+ attempt, kConnectAttempts, platform_port, kConnectDelay);
+ std::this_thread::sleep_for(kConnectDelay);
+ }
+ return status.takeError();
+}
+
+llvm::Error PlatformWebInspectorWasm::EnsureConnected() {
+ if (m_remote_platform_sp)
+ return llvm::Error::success();
+ return LaunchPlatformServer();
+}
+
+Status PlatformWebInspectorWasm::ConnectRemote(Args &args) {
+ if (args.GetArgumentCount() == 0)
+ return Status::FromError(LaunchPlatformServer());
+ return PlatformWasm::ConnectRemote(args);
+}
+
+ProcessSP PlatformWebInspectorWasm::Attach(ProcessAttachInfo &attach_info,
+ Debugger &debugger, Target *target,
+ Status &status) {
+ status = Status::FromError(EnsureConnected());
+ if (status.Fail())
+ return nullptr;
+ return PlatformWasm::Attach(attach_info, debugger, target, status);
+}
+
+uint32_t PlatformWebInspectorWasm::FindProcesses(
+ const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &proc_infos) {
+ if (llvm::Error err = EnsureConnected()) {
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Platform), std::move(err),
+ "EnsureConnected failed: {0}");
+ return 0;
+ }
+ return PlatformWasm::FindProcesses(match_info, proc_infos);
+}
+
+bool PlatformWebInspectorWasm::GetProcessInfo(lldb::pid_t pid,
+ ProcessInstanceInfo &proc_info) {
+ if (llvm::Error err = EnsureConnected()) {
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Platform), std::move(err),
+ "EnsureConnected failed: {0}");
+ return false;
+ }
+ return PlatformWasm::GetProcessInfo(pid, proc_info);
+}
+
+lldb::ProcessSP
+PlatformWebInspectorWasm::DebugProcess(ProcessLaunchInfo &launch_info,
+ Debugger &debugger, Target &target,
+ Status &error) {
+ error = Status::FromErrorStringWithFormatv("{0} does not support launching",
+ GetPluginNameStatic());
+ return nullptr;
+}
diff --git a/lldb/source/Plugins/Platform/WebAssembly/PlatformWebInspectorWasm.h b/lldb/source/Plugins/Platform/WebAssembly/PlatformWebInspectorWasm.h
new file mode 100644
index 0000000000000..52286b4532ebc
--- /dev/null
+++ b/lldb/source/Plugins/Platform/WebAssembly/PlatformWebInspectorWasm.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_WEBASSEMBLY_PLATFORMWEBINSPECTORWASM_H
+#define LLDB_SOURCE_PLUGINS_PLATFORM_WEBASSEMBLY_PLATFORMWEBINSPECTORWASM_H
+
+#include "PlatformWasm.h"
+
+namespace lldb_private {
+
+class PlatformWebInspectorWasm : public PlatformWasm {
+public:
+ static void Initialize();
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() { return "webinspector-wasm"; }
+ static llvm::StringRef GetPluginDescriptionStatic();
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+ llvm::StringRef GetDescription() override {
+ return GetPluginDescriptionStatic();
+ }
+
+ ~PlatformWebInspectorWasm() override;
+
+ Status ConnectRemote(Args &args) override;
+
+ lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
+ Target *target, Status &status) override;
+
+ lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info,
+ Debugger &debugger, Target &target,
+ Status &error) override;
+
+ uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &proc_infos) override;
+
+ bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override;
+
+private:
+ static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+
+ PlatformWebInspectorWasm() = default;
+
+ llvm::Error LaunchPlatformServer();
+ llvm::Error EnsureConnected();
+
+ lldb::pid_t m_server_pid = LLDB_INVALID_PROCESS_ID;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_PLATFORM_WEBASSEMBLY_PLATFORMWEBINSPECTORWASM_H
|
|
Can you describe this and contrast with the existing platform? I guess that |
|
Also, more changes to come, or worth a release note already? |
Yes that's right. The existing "wasm" platform handles WebAssembly generally (hence why we inherit from it here), and allows you to configure a runtime to launch under. This one does the inverse, and only supports attaching to an already running WebAssembly instance in Safari. The workflow here is always Release note sounds good 👍 Edit: updated the PR description |
Add a new PlatformWebInspectorWasm, which is a Wasm platform that automatically connects to the WebInspector platform server. The existing "wasm" platform handles WebAssembly generally and allows you to configure a runtime to launch under. The "webinspector-wasm" platform does the inverse, and only supports attaching to an already running WebAssembly instance in Safari. The workflow here is always `platform process list` followed by `platform process attach`. This explains why you can only force create this platform and it's never automatically selected when loading a Wasm target. (cherry picked from commit 7119610)
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/141/builds/16719 Here is the relevant piece of the build log for the reference |
This is flakey on the buildbot. https://lab.llvm.org/buildbot/#/builders/141/builds/16719 as reported on llvm#188751. FAIL: test_step_over_with_python_api_dwarf (TestInlineStepping.TestInlineStepping.test_step_over_with_python_api_dwarf) Test stepping over and into inlined functions. ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 2019, in test_method return attrvalue(self) ^^^^^^^^^^^^^^^ File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 25, in test_step_over_with_python_api self.inline_stepping_step_over() File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 317, in inline_stepping_step_over self.run_step_sequence(step_sequence) File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 152, in run_step_sequence self.do_step(step_pattern[1], target_line_entry, test_stack_depth) File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 83, in do_step self.fail( AssertionError: Failed to stop due to step into operation stepping to: C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\calling.cpp:46
…189032) This is flakey on the buildbot. https://lab.llvm.org/buildbot/#/builders/141/builds/16719 as reported on #188751. ``` FAIL: test_step_over_with_python_api_dwarf (TestInlineStepping.TestInlineStepping.test_step_over_with_python_api_dwarf) Test stepping over and into inlined functions. ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 2019, in test_method return attrvalue(self) ^^^^^^^^^^^^^^^ File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 25, in test_step_over_with_python_api self.inline_stepping_step_over() File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 317, in inline_stepping_step_over self.run_step_sequence(step_sequence) File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 152, in run_step_sequence self.do_step(step_pattern[1], target_line_entry, test_stack_depth) File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 83, in do_step self.fail( AssertionError: Failed to stop due to step into operation stepping to: C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\calling.cpp:46 ```
…form [lldb] Add PlatformWebInspectorWasm (llvm#188751)
Add a new PlatformWebInspectorWasm, which is a Wasm platform that automatically connects to the WebInspector platform server. The existing "wasm" platform handles WebAssembly generally and allows you to configure a runtime to launch under. The "webinspector-wasm" platform does the inverse, and only supports attaching to an already running WebAssembly instance in Safari. The workflow here is always `platform process list` followed by `platform process attach`. This explains why you can only force create this platform and it's never automatically selected when loading a Wasm target.
…lvm#189032) This is flakey on the buildbot. https://lab.llvm.org/buildbot/#/builders/141/builds/16719 as reported on llvm#188751. ``` FAIL: test_step_over_with_python_api_dwarf (TestInlineStepping.TestInlineStepping.test_step_over_with_python_api_dwarf) Test stepping over and into inlined functions. ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 2019, in test_method return attrvalue(self) ^^^^^^^^^^^^^^^ File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 25, in test_step_over_with_python_api self.inline_stepping_step_over() File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 317, in inline_stepping_step_over self.run_step_sequence(step_sequence) File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 152, in run_step_sequence self.do_step(step_pattern[1], target_line_entry, test_stack_depth) File "C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\TestInlineStepping.py", line 83, in do_step self.fail( AssertionError: Failed to stop due to step into operation stepping to: C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\test\API\functionalities\inline-stepping\calling.cpp:46 ```
Add a new PlatformWebInspectorWasm, which is a Wasm platform that automatically connects to the WebInspector platform server.
The existing "wasm" platform handles WebAssembly generally and allows you to configure a runtime to launch under. The "webinspector-wasm" platform does the inverse, and only supports attaching to an already running WebAssembly instance in Safari. The workflow here is always
platform process listfollowed byplatform process attach. This explains why you can only force create this platform and it's never automatically selected when loading a Wasm target.