Skip to content

Commit 14080f6

Browse files
committed
Refactoring the socket management for lldb-dap server mode to use lldb/Host/Socket.h'.
1 parent b9713bb commit 14080f6

File tree

15 files changed

+197
-805
lines changed

15 files changed

+197
-805
lines changed

lldb/include/lldb/Host/Socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ class Socket : public IOObject {
152152
// If this Socket is connected then return the URI used to connect.
153153
virtual std::string GetRemoteConnectionURI() const { return ""; };
154154

155+
// If the Socket is listening then return the URI for clients to connect.
156+
virtual std::string GetListeningConnectionURI() const { return ""; }
157+
155158
protected:
156159
Socket(SocketProtocol protocol, bool should_close,
157160
bool m_child_process_inherit);

lldb/include/lldb/Host/common/TCPSocket.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class TCPSocket : public Socket {
5353

5454
std::string GetRemoteConnectionURI() const override;
5555

56+
std::string GetListeningConnectionURI() const override;
57+
5658
private:
5759
TCPSocket(NativeSocket socket, const TCPSocket &listen_socket);
5860

lldb/include/lldb/Host/posix/DomainSocket.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class DomainSocket : public Socket {
2828

2929
std::string GetRemoteConnectionURI() const override;
3030

31+
std::string GetListeningConnectionURI() const override;
32+
3133
protected:
3234
DomainSocket(SocketProtocol protocol, bool child_processes_inherit);
3335

lldb/packages/Python/lldbsuite/test/lldbtest.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -251,13 +251,6 @@ def which(program):
251251
return None
252252

253253

254-
def pickrandomport():
255-
"""Returns a random open port."""
256-
with socket.socket() as sock:
257-
sock.bind(("", 0))
258-
return sock.getsockname()[1]
259-
260-
261254
class ValueCheck:
262255
def __init__(
263256
self,

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,14 +1172,13 @@ def __init__(
11721172
)
11731173

11741174
if connection:
1175-
print("attempting connection", connection)
1176-
if connection.startswith("unix://"): # unix:///path
1175+
if connection.startswith("unix-connect://"): # unix-connect:///path
11771176
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
1178-
s.connect(connection.removeprefix("unix://"))
1179-
elif connection.startswith("tcp://"): # tcp://host:port
1180-
host, port = connection.removeprefix("tcp://").split(":", 1)
1177+
s.connect(connection.removeprefix("unix-connect://"))
1178+
elif connection.startswith("connection://"): # connection://[host]:port
1179+
host, port = connection.removeprefix("connection://").rsplit(":", 1)
11811180
# create_connection with try both ipv4 and ipv6.
1182-
s = socket.create_connection((host, int(port)))
1181+
s = socket.create_connection((host.strip("[]"), int(port)))
11831182
else:
11841183
raise ValueError("invalid connection: {}".format(connection))
11851184
DebugCommunication.__init__(
@@ -1213,16 +1212,16 @@ def launch(
12131212
if log_file:
12141213
adaptor_env["LLDBDAP_LOG"] = log_file
12151214

1216-
if os.uname().sysname == "Darwin":
1217-
adaptor_env["NSUnbufferedIO"] = "YES"
1218-
12191215
args = [executable]
1216+
bufsize = -1
12201217
if connection:
1218+
bufsize = 0
12211219
args.append("--connection")
12221220
args.append(connection)
12231221

12241222
proc = subprocess.Popen(
12251223
args,
1224+
bufsize=bufsize,
12261225
stdin=subprocess.PIPE,
12271226
stdout=subprocess.PIPE,
12281227
stderr=sys.stdout,
@@ -1233,29 +1232,20 @@ def launch(
12331232
# If a conneciton is specified, lldb-dap will print the listening
12341233
# address once the listener is made to stdout. The listener is
12351234
# formatted like `tcp://host:port` or `unix:///path`.
1236-
with selectors.DefaultSelector() as sel:
1237-
print("Reading stdout for the listening connection")
1238-
os.set_blocking(proc.stdout.fileno(), False)
1239-
stdout_key = sel.register(proc.stdout, selectors.EVENT_READ)
1240-
rdy_fds = sel.select(timeout=10.0)
1241-
for key, _ in rdy_fds:
1242-
if key != stdout_key:
1243-
continue
1244-
1245-
outs = proc.stdout.read(1024).decode()
1246-
os.set_blocking(proc.stdout.fileno(), True)
1247-
for line in outs.split("\n"):
1248-
if not line.startswith("Listening for: "):
1249-
continue
1250-
# If the listener expanded into multiple addresses, use the first.
1251-
connection = line.removeprefix("Listening for: ").split(",")[0]
1252-
print("")
1253-
return proc, connection
1235+
expected_prefix = "Listening for: "
1236+
out = proc.stdout.readline().decode()
1237+
if not out.startswith(expected_prefix):
12541238
proc.kill()
12551239
raise ValueError(
1256-
"lldb-dap started with a connection but failed to write the listening address to stdout."
1240+
"lldb-dap failed to print listening address, expected '{}', got '{}'".format(
1241+
expected_prefix, out
1242+
)
12571243
)
12581244

1245+
# If the listener expanded into multiple addresses, use the first.
1246+
connection = out.removeprefix(expected_prefix).rstrip("\r\n")
1247+
return proc, connection
1248+
12591249
return proc, None
12601250

12611251

lldb/source/Host/common/TCPSocket.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ std::string TCPSocket::GetLocalIPAddress() const {
8484
socklen_t sock_addr_len = sock_addr.GetMaxLength();
8585
if (::getsockname(m_socket, sock_addr, &sock_addr_len) == 0)
8686
return sock_addr.GetIPAddress();
87+
} else if (!m_listen_sockets.empty()) {
88+
SocketAddress sock_addr;
89+
socklen_t sock_addr_len = sock_addr.GetMaxLength();
90+
if (::getsockname(m_listen_sockets.begin()->first, sock_addr,
91+
&sock_addr_len) == 0)
92+
return sock_addr.GetIPAddress();
8793
}
8894
return "";
8995
}
@@ -118,6 +124,15 @@ std::string TCPSocket::GetRemoteConnectionURI() const {
118124
return "";
119125
}
120126

127+
std::string TCPSocket::GetListeningConnectionURI() const {
128+
if (!m_listen_sockets.empty()) {
129+
return std::string(llvm::formatv(
130+
"connection://[{0}]:{1}", GetLocalIPAddress(), GetLocalPortNumber()));
131+
}
132+
133+
return "";
134+
}
135+
121136
Status TCPSocket::CreateSocket(int domain) {
122137
Status error;
123138
if (IsValid())
@@ -180,8 +195,9 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) {
180195

181196
if (host_port->hostname == "*")
182197
host_port->hostname = "0.0.0.0";
183-
std::vector<SocketAddress> addresses = SocketAddress::GetAddressInfo(
184-
host_port->hostname.c_str(), nullptr, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
198+
std::vector<SocketAddress> addresses =
199+
SocketAddress::GetAddressInfo(host_port->hostname.c_str(), nullptr,
200+
AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
185201
for (SocketAddress &address : addresses) {
186202
int fd = Socket::CreateSocket(address.GetFamily(), kType, IPPROTO_TCP,
187203
m_child_processes_inherit, error);
@@ -195,7 +211,7 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) {
195211
}
196212

197213
SocketAddress listen_address = address;
198-
if(!listen_address.IsLocalhost())
214+
if (!listen_address.IsLocalhost())
199215
listen_address.SetToAnyAddress(address.GetFamily(), host_port->port);
200216
else
201217
listen_address.SetPort(host_port->port);

lldb/source/Host/posix/DomainSocket.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ Status DomainSocket::Connect(llvm::StringRef name) {
9090
if (error.Fail())
9191
return error;
9292
if (llvm::sys::RetryAfterSignal(-1, ::connect, GetNativeSocket(),
93-
(struct sockaddr *)&saddr_un, saddr_un_len) < 0)
93+
(struct sockaddr *)&saddr_un,
94+
saddr_un_len) < 0)
9495
SetLastError(error);
9596

9697
return error;
@@ -181,3 +182,17 @@ std::string DomainSocket::GetRemoteConnectionURI() const {
181182
"{0}://{1}",
182183
GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect", name);
183184
}
185+
186+
std::string DomainSocket::GetListeningConnectionURI() const {
187+
if (m_socket == kInvalidSocketValue)
188+
return "";
189+
190+
struct sockaddr_un addr;
191+
bzero(&addr, sizeof(struct sockaddr_un));
192+
addr.sun_family = AF_UNIX;
193+
socklen_t addr_len = sizeof(struct sockaddr_un);
194+
if (::getsockname(m_socket, (struct sockaddr *)&addr, &addr_len) != 0)
195+
return "";
196+
197+
return llvm::formatv("unix-connect://{0}", addr.sun_path);
198+
}

lldb/tools/lldb-dap/CMakeLists.txt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
if ( CMAKE_SYSTEM_NAME MATCHES "Windows" OR CMAKE_SYSTEM_NAME MATCHES "NetBSD" )
2-
list(APPEND extra_libs lldbHost)
3-
endif ()
4-
51
if (HAVE_LIBPTHREAD)
62
list(APPEND extra_libs pthread)
73
endif ()
@@ -37,12 +33,12 @@ add_lldb_tool(lldb-dap
3733
OutputRedirector.cpp
3834
ProgressEvent.cpp
3935
RunInTerminal.cpp
40-
Socket.cpp
4136
SourceBreakpoint.cpp
4237
Watchpoint.cpp
4338

4439
LINK_LIBS
4540
liblldb
41+
lldbHost
4642
${extra_libs}
4743

4844
LINK_COMPONENTS

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <chrono>
1010
#include <cstdarg>
11+
#include <fstream>
1112
#include <mutex>
1213

1314
#include "DAP.h"
@@ -34,7 +35,7 @@ using namespace lldb_dap;
3435

3536
namespace lldb_dap {
3637

37-
DAP::DAP(llvm::StringRef path, llvm::raw_ostream *log, ReplMode repl_mode,
38+
DAP::DAP(llvm::StringRef path, std::ofstream *log, ReplMode repl_mode,
3839
std::vector<std::string> pre_init_commands)
3940
: debug_adaptor_path(path), broadcaster("lldb-dap"), log(log),
4041
exception_breakpoints(), pre_init_commands(pre_init_commands),
@@ -66,8 +67,8 @@ llvm::Error DAP::ConfigureIO(int out_fd, int err_fd) {
6667
return Err;
6768
}
6869

69-
out = lldb::SBFile(new_stdout_fd.get(), "w", false);
70-
err = lldb::SBFile(new_stderr_fd.get(), "w", false);
70+
out = lldb::SBFile(new_stdout_fd.get(), "w", true);
71+
err = lldb::SBFile(new_stderr_fd.get(), "w", true);
7172

7273
return llvm::Error::success();
7374
}
@@ -207,9 +208,9 @@ void DAP::SendJSON(const llvm::json::Value &json) {
207208
if (log) {
208209
auto now = std::chrono::duration<double>(
209210
std::chrono::system_clock::now().time_since_epoch());
210-
*log << llvm::formatv("{0:f9} <-- ", now.count()).str() << "\n"
211+
*log << llvm::formatv("{0:f9} <-- ", now.count()).str() << std::endl
211212
<< "Content-Length: " << json_str.size() << "\r\n\r\n"
212-
<< llvm::formatv("{0:2}", json).str() << "\n";
213+
<< llvm::formatv("{0:2}", json).str() << std::endl;
213214
}
214215
}
215216

@@ -237,8 +238,8 @@ std::string DAP::ReadJSON() {
237238
if (log) {
238239
auto now = std::chrono::duration<double>(
239240
std::chrono::system_clock::now().time_since_epoch());
240-
*log << llvm::formatv("{0:f9} --> ", now.count()).str()
241-
<< "\nContent-Length: " << length << "\r\n\r\n";
241+
*log << llvm::formatv("{0:f9} --> ", now.count()).str() << std::endl
242+
<< "Content-Length: " << length << "\r\n\r\n";
242243
}
243244
return json_str;
244245
}

lldb/tools/lldb-dap/DAP.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ struct DAP {
145145
lldb::SBBroadcaster broadcaster;
146146
std::thread event_thread;
147147
std::thread progress_event_thread;
148-
llvm::raw_ostream *log;
148+
std::ofstream *log;
149149
llvm::StringMap<SourceBreakpointMap> source_breakpoints;
150150
FunctionBreakpointMap function_breakpoints;
151151
InstructionBreakpointMap instruction_breakpoints;
@@ -197,7 +197,7 @@ struct DAP {
197197
// will contain that expression.
198198
std::string last_nonempty_var_expression;
199199

200-
DAP(llvm::StringRef path, llvm::raw_ostream *log, ReplMode repl_mode,
200+
DAP(llvm::StringRef path, std::ofstream *log, ReplMode repl_mode,
201201
std::vector<std::string> pre_init_commands);
202202
~DAP();
203203

lldb/tools/lldb-dap/IOStream.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "IOStream.h"
10-
#include "llvm/Support/raw_ostream.h"
10+
#include <fstream>
1111
#include <string>
1212

1313
#if defined(_WIN32)
@@ -86,7 +86,7 @@ bool OutputStream::write_full(llvm::StringRef str) {
8686
return true;
8787
}
8888

89-
bool InputStream::read_full(llvm::raw_ostream *log, size_t length,
89+
bool InputStream::read_full(std::ofstream *log, size_t length,
9090
std::string &text) {
9191
std::string data;
9292
data.resize(length);
@@ -130,7 +130,7 @@ bool InputStream::read_full(llvm::raw_ostream *log, size_t length,
130130
return true;
131131
}
132132

133-
bool InputStream::read_line(llvm::raw_ostream *log, std::string &line) {
133+
bool InputStream::read_line(std::ofstream *log, std::string &line) {
134134
line.clear();
135135
while (true) {
136136
if (!read_full(log, 1, line))
@@ -143,8 +143,7 @@ bool InputStream::read_line(llvm::raw_ostream *log, std::string &line) {
143143
return true;
144144
}
145145

146-
bool InputStream::read_expected(llvm::raw_ostream *log,
147-
llvm::StringRef expected) {
146+
bool InputStream::read_expected(std::ofstream *log, llvm::StringRef expected) {
148147
std::string result;
149148
if (!read_full(log, expected.size(), result))
150149
return false;

lldb/tools/lldb-dap/IOStream.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ typedef int SOCKET;
2222
#endif
2323

2424
#include "llvm/ADT/StringRef.h"
25-
#include "llvm/Support/raw_ostream.h"
25+
#include <fstream>
2626
#include <string>
2727

2828
// Windows requires different system calls for dealing with sockets and other
@@ -51,11 +51,11 @@ struct StreamDescriptor {
5151
struct InputStream {
5252
StreamDescriptor descriptor;
5353

54-
bool read_full(llvm::raw_ostream *log, size_t length, std::string &text);
54+
bool read_full(std::ofstream *log, size_t length, std::string &text);
5555

56-
bool read_line(llvm::raw_ostream *log, std::string &line);
56+
bool read_line(std::ofstream *log, std::string &line);
5757

58-
bool read_expected(llvm::raw_ostream *log, llvm::StringRef expected);
58+
bool read_expected(std::ofstream *log, llvm::StringRef expected);
5959
};
6060

6161
struct OutputStream {

0 commit comments

Comments
 (0)