https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/144770
>From adea12ff55b0a8259fc4c4470726cde8d35f4ffa Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Wed, 18 Jun 2025 13:03:51 -0500 Subject: [PATCH 1/2] [lldb-dap] Make connection URLs match lldb Use the same scheme as ConnectionFileDescriptor::Connect and use "listen" and "accept". Addresses feedback from a Pavel in a different PR [1]. [1] https://github.com/llvm/llvm-project/pull/143628#discussion_r2152225200 --- lldb/include/lldb/Host/Socket.h | 9 ++++++ lldb/source/Host/common/Socket.cpp | 32 +++++++++++++++++-- .../tools/lldb-dap/server/TestDAP_server.py | 6 ++-- lldb/tools/lldb-dap/Options.td | 4 +-- lldb/tools/lldb-dap/tool/lldb-dap.cpp | 27 ++++++++++------ 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/lldb/include/lldb/Host/Socket.h b/lldb/include/lldb/Host/Socket.h index 4585eac12efb9..c313aa4f6d26b 100644 --- a/lldb/include/lldb/Host/Socket.h +++ b/lldb/include/lldb/Host/Socket.h @@ -74,6 +74,11 @@ class Socket : public IOObject { ProtocolUnixAbstract }; + enum SocketMode { + ModeAccept, + ModeConnect, + }; + struct HostAndPort { std::string hostname; uint16_t port; @@ -83,6 +88,10 @@ class Socket : public IOObject { } }; + using ProtocolModePair = std::pair<SocketProtocol, SocketMode>; + static std::optional<ProtocolModePair> + GetProtocolAndMode(llvm::StringRef scheme); + static const NativeSocket kInvalidSocketValue; ~Socket() override; diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp index 76f74401ac4d0..5c5cd653c3d9e 100644 --- a/lldb/source/Host/common/Socket.cpp +++ b/lldb/source/Host/common/Socket.cpp @@ -271,7 +271,8 @@ Socket::UdpConnect(llvm::StringRef host_and_port) { return UDPSocket::CreateConnected(host_and_port); } -llvm::Expected<Socket::HostAndPort> Socket::DecodeHostAndPort(llvm::StringRef host_and_port) { +llvm::Expected<Socket::HostAndPort> +Socket::DecodeHostAndPort(llvm::StringRef host_and_port) { static llvm::Regex g_regex("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)"); HostAndPort ret; llvm::SmallVector<llvm::StringRef, 3> matches; @@ -347,8 +348,8 @@ Status Socket::Write(const void *buf, size_t &num_bytes) { ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)", static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, - static_cast<uint64_t>(src_len), - static_cast<int64_t>(bytes_sent), error.AsCString()); + static_cast<uint64_t>(src_len), static_cast<int64_t>(bytes_sent), + error.AsCString()); } return error; @@ -476,3 +477,28 @@ llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS, const Socket::HostAndPort &HP) { return OS << '[' << HP.hostname << ']' << ':' << HP.port; } + +std::optional<Socket::ProtocolModePair> +Socket::GetProtocolAndMode(llvm::StringRef scheme) { + // Keep in sync with ConnectionFileDescriptor::Connect. + return llvm::StringSwitch<std::optional<ProtocolModePair>>(scheme) + .Case("listen", ProtocolModePair{SocketProtocol::ProtocolTcp, + SocketMode::ModeAccept}) + .Cases("accept", "unix-accept", + ProtocolModePair{SocketProtocol::ProtocolUnixDomain, + SocketMode::ModeAccept}) + .Case("unix-abstract-accept", + ProtocolModePair{SocketProtocol::ProtocolUnixAbstract, + SocketMode::ModeAccept}) + .Cases("connect", "tcp-connect", + ProtocolModePair{SocketProtocol::ProtocolTcp, + SocketMode::ModeConnect}) + .Case("udp", ProtocolModePair{SocketProtocol::ProtocolTcp, + SocketMode::ModeConnect}) + .Case("unix-connect", ProtocolModePair{SocketProtocol::ProtocolUnixDomain, + SocketMode::ModeConnect}) + .Case("unix-abstract-connect", + ProtocolModePair{SocketProtocol::ProtocolUnixAbstract, + SocketMode::ModeConnect}) + .Default(std::nullopt); +} diff --git a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py index ed17044a220d4..592a4cfb0a88b 100644 --- a/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py +++ b/lldb/test/API/tools/lldb-dap/server/TestDAP_server.py @@ -54,7 +54,7 @@ def test_server_port(self): Test launching a binary with a lldb-dap in server mode on a specific port. """ self.build() - (_, connection) = self.start_server(connection="tcp://localhost:0") + (_, connection) = self.start_server(connection="listen://localhost:0") self.run_debug_session(connection, "Alice") self.run_debug_session(connection, "Bob") @@ -72,7 +72,7 @@ def cleanup(): self.addTearDownHook(cleanup) self.build() - (_, connection) = self.start_server(connection="unix://" + name) + (_, connection) = self.start_server(connection="accept://" + name) self.run_debug_session(connection, "Alice") self.run_debug_session(connection, "Bob") @@ -82,7 +82,7 @@ def test_server_interrupt(self): Test launching a binary with lldb-dap in server mode and shutting down the server while the debug session is still active. """ self.build() - (process, connection) = self.start_server(connection="tcp://localhost:0") + (process, connection) = self.start_server(connection="listen://localhost:0") self.dap_server = dap_server.DebugAdapterServer( connection=connection, ) diff --git a/lldb/tools/lldb-dap/Options.td b/lldb/tools/lldb-dap/Options.td index aecf91797ac70..867753e9294a6 100644 --- a/lldb/tools/lldb-dap/Options.td +++ b/lldb/tools/lldb-dap/Options.td @@ -28,8 +28,8 @@ def connection MetaVarName<"<connection>">, HelpText< "Communicate with the lldb-dap tool over the specified connection. " - "Connections are specified like 'tcp://[host]:port' or " - "'unix:///path'.">; + "Connections are specified like 'listen://[host]:port' or " + "'accept:///path'.">; def launch_target: S<"launch-target">, MetaVarName<"<target>">, diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp b/lldb/tools/lldb-dap/tool/lldb-dap.cpp index 9b9de5e21a742..853a95fd38f38 100644 --- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp @@ -226,23 +226,32 @@ static llvm::Expected<std::pair<Socket::SocketProtocol, std::string>> validateConnection(llvm::StringRef conn) { auto uri = lldb_private::URI::Parse(conn); - if (uri && (uri->scheme == "tcp" || uri->scheme == "connect" || - !uri->hostname.empty() || uri->port)) { + auto make_error = [conn]() -> llvm::Error { + return llvm::createStringError( + "Unsupported connection specifier, expected 'accept://path' or " + "'listen://[host]:port', got '%s'.", + conn.str().c_str()); + }; + + if (!uri) + return make_error(); + + std::optional<Socket::ProtocolModePair> protocol_and_mode = + Socket::GetProtocolAndMode(uri->scheme); + if (!protocol_and_mode || protocol_and_mode->second != Socket::ModeAccept) + return make_error(); + + if (protocol_and_mode->first == Socket::ProtocolTcp) { return std::make_pair( Socket::ProtocolTcp, formatv("[{0}]:{1}", uri->hostname.empty() ? "0.0.0.0" : uri->hostname, uri->port.value_or(0))); } - if (uri && (uri->scheme == "unix" || uri->scheme == "unix-connect" || - uri->path != "/")) { + if (protocol_and_mode->first == Socket::ProtocolUnixDomain) return std::make_pair(Socket::ProtocolUnixDomain, uri->path.str()); - } - return llvm::createStringError( - "Unsupported connection specifier, expected 'unix-connect:///path' or " - "'connect://[host]:port', got '%s'.", - conn.str().c_str()); + return make_error(); } static llvm::Error >From cff1850ef89b9fc5224bb22e175c5a6eedb50081 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Wed, 18 Jun 2025 15:48:31 -0500 Subject: [PATCH 2/2] Address review feedback --- lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts | 2 +- lldb/tools/lldb-dap/tool/lldb-dap.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts b/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts index f40dbf049a4bb..79573ec7342b1 100644 --- a/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts +++ b/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts @@ -26,7 +26,7 @@ export class LLDBDapServer implements vscode.Disposable { args: string[], options?: child_process.SpawnOptionsWithoutStdio, ): Promise<{ host: string; port: number } | undefined> { - const dapArgs = [...args, "--connection", "connect://localhost:0"]; + const dapArgs = [...args, "--connection", "listen://localhost:0" ]; if (!(await this.shouldContinueStartup(dapPath, dapArgs))) { return undefined; } diff --git a/lldb/tools/lldb-dap/tool/lldb-dap.cpp b/lldb/tools/lldb-dap/tool/lldb-dap.cpp index 853a95fd38f38..2799d10ae84ba 100644 --- a/lldb/tools/lldb-dap/tool/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/tool/lldb-dap.cpp @@ -127,7 +127,7 @@ static void PrintHelp(LLDBDAPOptTable &table, llvm::StringRef tool_name) { parent over stdio. Passing a --connection URI will cause lldb-dap to listen for a connection in the specified mode. - lldb-dap --connection connection://localhost:<port> + lldb-dap --connection listen://localhost:<port> Passing --wait-for-debugger will pause the process at startup and wait for a debugger to attach to the process. @@ -228,7 +228,7 @@ validateConnection(llvm::StringRef conn) { auto make_error = [conn]() -> llvm::Error { return llvm::createStringError( - "Unsupported connection specifier, expected 'accept://path' or " + "Unsupported connection specifier, expected 'accept:///path' or " "'listen://[host]:port', got '%s'.", conn.str().c_str()); }; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits