Skip to content

Commit 4f991cc

Browse files
authored
[lldb-dap] Make connection URLs match lldb (#144770)
Use the same scheme as ConnectionFileDescriptor::Connect and use "listen" and "accept". Addresses feedback from a Pavel in a different PR [1]. [1] #143628 (comment)
1 parent 513bcf6 commit 4f991cc

File tree

6 files changed

+63
-19
lines changed

6 files changed

+63
-19
lines changed

lldb/include/lldb/Host/Socket.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ class Socket : public IOObject {
7474
ProtocolUnixAbstract
7575
};
7676

77+
enum SocketMode {
78+
ModeAccept,
79+
ModeConnect,
80+
};
81+
7782
struct HostAndPort {
7883
std::string hostname;
7984
uint16_t port;
@@ -83,6 +88,10 @@ class Socket : public IOObject {
8388
}
8489
};
8590

91+
using ProtocolModePair = std::pair<SocketProtocol, SocketMode>;
92+
static std::optional<ProtocolModePair>
93+
GetProtocolAndMode(llvm::StringRef scheme);
94+
8695
static const NativeSocket kInvalidSocketValue;
8796

8897
~Socket() override;

lldb/source/Host/common/Socket.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@ Socket::UdpConnect(llvm::StringRef host_and_port) {
271271
return UDPSocket::CreateConnected(host_and_port);
272272
}
273273

274-
llvm::Expected<Socket::HostAndPort> Socket::DecodeHostAndPort(llvm::StringRef host_and_port) {
274+
llvm::Expected<Socket::HostAndPort>
275+
Socket::DecodeHostAndPort(llvm::StringRef host_and_port) {
275276
static llvm::Regex g_regex("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)");
276277
HostAndPort ret;
277278
llvm::SmallVector<llvm::StringRef, 3> matches;
@@ -347,8 +348,8 @@ Status Socket::Write(const void *buf, size_t &num_bytes) {
347348
", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
348349
" (error = %s)",
349350
static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf,
350-
static_cast<uint64_t>(src_len),
351-
static_cast<int64_t>(bytes_sent), error.AsCString());
351+
static_cast<uint64_t>(src_len), static_cast<int64_t>(bytes_sent),
352+
error.AsCString());
352353
}
353354

354355
return error;
@@ -476,3 +477,28 @@ llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS,
476477
const Socket::HostAndPort &HP) {
477478
return OS << '[' << HP.hostname << ']' << ':' << HP.port;
478479
}
480+
481+
std::optional<Socket::ProtocolModePair>
482+
Socket::GetProtocolAndMode(llvm::StringRef scheme) {
483+
// Keep in sync with ConnectionFileDescriptor::Connect.
484+
return llvm::StringSwitch<std::optional<ProtocolModePair>>(scheme)
485+
.Case("listen", ProtocolModePair{SocketProtocol::ProtocolTcp,
486+
SocketMode::ModeAccept})
487+
.Cases("accept", "unix-accept",
488+
ProtocolModePair{SocketProtocol::ProtocolUnixDomain,
489+
SocketMode::ModeAccept})
490+
.Case("unix-abstract-accept",
491+
ProtocolModePair{SocketProtocol::ProtocolUnixAbstract,
492+
SocketMode::ModeAccept})
493+
.Cases("connect", "tcp-connect",
494+
ProtocolModePair{SocketProtocol::ProtocolTcp,
495+
SocketMode::ModeConnect})
496+
.Case("udp", ProtocolModePair{SocketProtocol::ProtocolTcp,
497+
SocketMode::ModeConnect})
498+
.Case("unix-connect", ProtocolModePair{SocketProtocol::ProtocolUnixDomain,
499+
SocketMode::ModeConnect})
500+
.Case("unix-abstract-connect",
501+
ProtocolModePair{SocketProtocol::ProtocolUnixAbstract,
502+
SocketMode::ModeConnect})
503+
.Default(std::nullopt);
504+
}

lldb/test/API/tools/lldb-dap/server/TestDAP_server.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def test_server_port(self):
5454
Test launching a binary with a lldb-dap in server mode on a specific port.
5555
"""
5656
self.build()
57-
(_, connection) = self.start_server(connection="tcp://localhost:0")
57+
(_, connection) = self.start_server(connection="listen://localhost:0")
5858
self.run_debug_session(connection, "Alice")
5959
self.run_debug_session(connection, "Bob")
6060

@@ -72,7 +72,7 @@ def cleanup():
7272
self.addTearDownHook(cleanup)
7373

7474
self.build()
75-
(_, connection) = self.start_server(connection="unix://" + name)
75+
(_, connection) = self.start_server(connection="accept://" + name)
7676
self.run_debug_session(connection, "Alice")
7777
self.run_debug_session(connection, "Bob")
7878

@@ -82,7 +82,7 @@ def test_server_interrupt(self):
8282
Test launching a binary with lldb-dap in server mode and shutting down the server while the debug session is still active.
8383
"""
8484
self.build()
85-
(process, connection) = self.start_server(connection="tcp://localhost:0")
85+
(process, connection) = self.start_server(connection="listen://localhost:0")
8686
self.dap_server = dap_server.DebugAdapterServer(
8787
connection=connection,
8888
)

lldb/tools/lldb-dap/Options.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ def connection
2828
MetaVarName<"<connection>">,
2929
HelpText<
3030
"Communicate with the lldb-dap tool over the specified connection. "
31-
"Connections are specified like 'tcp://[host]:port' or "
32-
"'unix:///path'.">;
31+
"Connections are specified like 'listen://[host]:port' or "
32+
"'accept:///path'.">;
3333

3434
def launch_target: S<"launch-target">,
3535
MetaVarName<"<target>">,

lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class LLDBDapServer implements vscode.Disposable {
2626
args: string[],
2727
options?: child_process.SpawnOptionsWithoutStdio,
2828
): Promise<{ host: string; port: number } | undefined> {
29-
const dapArgs = [...args, "--connection", "connect://localhost:0"];
29+
const dapArgs = [...args, "--connection", "listen://localhost:0" ];
3030
if (!(await this.shouldContinueStartup(dapPath, dapArgs))) {
3131
return undefined;
3232
}

lldb/tools/lldb-dap/tool/lldb-dap.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ static void PrintHelp(LLDBDAPOptTable &table, llvm::StringRef tool_name) {
127127
parent over stdio. Passing a --connection URI will cause lldb-dap to listen
128128
for a connection in the specified mode.
129129
130-
lldb-dap --connection connection://localhost:<port>
130+
lldb-dap --connection listen://localhost:<port>
131131
132132
Passing --wait-for-debugger will pause the process at startup and wait for a
133133
debugger to attach to the process.
@@ -226,23 +226,32 @@ static llvm::Expected<std::pair<Socket::SocketProtocol, std::string>>
226226
validateConnection(llvm::StringRef conn) {
227227
auto uri = lldb_private::URI::Parse(conn);
228228

229-
if (uri && (uri->scheme == "tcp" || uri->scheme == "connect" ||
230-
!uri->hostname.empty() || uri->port)) {
229+
auto make_error = [conn]() -> llvm::Error {
230+
return llvm::createStringError(
231+
"Unsupported connection specifier, expected 'accept:///path' or "
232+
"'listen://[host]:port', got '%s'.",
233+
conn.str().c_str());
234+
};
235+
236+
if (!uri)
237+
return make_error();
238+
239+
std::optional<Socket::ProtocolModePair> protocol_and_mode =
240+
Socket::GetProtocolAndMode(uri->scheme);
241+
if (!protocol_and_mode || protocol_and_mode->second != Socket::ModeAccept)
242+
return make_error();
243+
244+
if (protocol_and_mode->first == Socket::ProtocolTcp) {
231245
return std::make_pair(
232246
Socket::ProtocolTcp,
233247
formatv("[{0}]:{1}", uri->hostname.empty() ? "0.0.0.0" : uri->hostname,
234248
uri->port.value_or(0)));
235249
}
236250

237-
if (uri && (uri->scheme == "unix" || uri->scheme == "unix-connect" ||
238-
uri->path != "/")) {
251+
if (protocol_and_mode->first == Socket::ProtocolUnixDomain)
239252
return std::make_pair(Socket::ProtocolUnixDomain, uri->path.str());
240-
}
241253

242-
return llvm::createStringError(
243-
"Unsupported connection specifier, expected 'unix-connect:///path' or "
244-
"'connect://[host]:port', got '%s'.",
245-
conn.str().c_str());
254+
return make_error();
246255
}
247256

248257
static llvm::Error

0 commit comments

Comments
 (0)