Skip to content

Commit d26fd6c

Browse files
slydimanadrian-prantl
authored andcommitted
[lldb][NFC] Moved the SharedSocket class to Socket.* (llvm#104787)
This is the prerequisite for llvm#104238. (cherry picked from commit 06ccd32)
1 parent 6225500 commit d26fd6c

File tree

3 files changed

+114
-112
lines changed

3 files changed

+114
-112
lines changed

lldb/include/lldb/Host/Socket.h

+24
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "lldb/Utility/Status.h"
2020

2121
#ifdef _WIN32
22+
#include "lldb/Host/Pipe.h"
2223
#include "lldb/Host/windows/windows.h"
2324
#include <winsock2.h>
2425
#include <ws2tcpip.h>
@@ -32,12 +33,35 @@ namespace lldb_private {
3233

3334
#if defined(_WIN32)
3435
typedef SOCKET NativeSocket;
36+
typedef lldb::pipe_t shared_fd_t;
3537
#else
3638
typedef int NativeSocket;
39+
typedef NativeSocket shared_fd_t;
3740
#endif
41+
class Socket;
3842
class TCPSocket;
3943
class UDPSocket;
4044

45+
class SharedSocket {
46+
public:
47+
static const shared_fd_t kInvalidFD;
48+
49+
SharedSocket(const Socket *socket, Status &error);
50+
51+
shared_fd_t GetSendableFD() { return m_fd; }
52+
53+
Status CompleteSending(lldb::pid_t child_pid);
54+
55+
static Status GetNativeSocket(shared_fd_t fd, NativeSocket &socket);
56+
57+
private:
58+
#ifdef _WIN32
59+
Pipe m_socket_pipe;
60+
NativeSocket m_socket;
61+
#endif
62+
shared_fd_t m_fd;
63+
};
64+
4165
class Socket : public IOObject {
4266
public:
4367
enum SocketProtocol {

lldb/source/Host/common/Socket.cpp

+76
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,12 @@ using namespace lldb_private;
5656
typedef const char *set_socket_option_arg_type;
5757
typedef char *get_socket_option_arg_type;
5858
const NativeSocket Socket::kInvalidSocketValue = INVALID_SOCKET;
59+
const shared_fd_t SharedSocket::kInvalidFD = LLDB_INVALID_PIPE;
5960
#else // #if defined(_WIN32)
6061
typedef const void *set_socket_option_arg_type;
6162
typedef void *get_socket_option_arg_type;
6263
const NativeSocket Socket::kInvalidSocketValue = -1;
64+
const shared_fd_t SharedSocket::kInvalidFD = Socket::kInvalidSocketValue;
6365
#endif // #if defined(_WIN32)
6466

6567
static bool IsInterrupted() {
@@ -70,6 +72,80 @@ static bool IsInterrupted() {
7072
#endif
7173
}
7274

75+
SharedSocket::SharedSocket(const Socket *socket, Status &error) {
76+
#ifdef _WIN32
77+
m_socket = socket->GetNativeSocket();
78+
m_fd = kInvalidFD;
79+
80+
// Create a pipe to transfer WSAPROTOCOL_INFO to the child process.
81+
error = m_socket_pipe.CreateNew(true);
82+
if (error.Fail())
83+
return;
84+
85+
m_fd = m_socket_pipe.GetReadPipe();
86+
#else
87+
m_fd = socket->GetNativeSocket();
88+
error = Status();
89+
#endif
90+
}
91+
92+
Status SharedSocket::CompleteSending(lldb::pid_t child_pid) {
93+
#ifdef _WIN32
94+
// Transfer WSAPROTOCOL_INFO to the child process.
95+
m_socket_pipe.CloseReadFileDescriptor();
96+
97+
WSAPROTOCOL_INFO protocol_info;
98+
if (::WSADuplicateSocket(m_socket, child_pid, &protocol_info) ==
99+
SOCKET_ERROR) {
100+
int last_error = ::WSAGetLastError();
101+
return Status("WSADuplicateSocket() failed, error: %d", last_error);
102+
}
103+
104+
size_t num_bytes;
105+
Status error =
106+
m_socket_pipe.WriteWithTimeout(&protocol_info, sizeof(protocol_info),
107+
std::chrono::seconds(10), num_bytes);
108+
if (error.Fail())
109+
return error;
110+
if (num_bytes != sizeof(protocol_info))
111+
return Status("WriteWithTimeout(WSAPROTOCOL_INFO) failed: %d bytes",
112+
num_bytes);
113+
#endif
114+
return Status();
115+
}
116+
117+
Status SharedSocket::GetNativeSocket(shared_fd_t fd, NativeSocket &socket) {
118+
#ifdef _WIN32
119+
socket = Socket::kInvalidSocketValue;
120+
// Read WSAPROTOCOL_INFO from the parent process and create NativeSocket.
121+
WSAPROTOCOL_INFO protocol_info;
122+
{
123+
Pipe socket_pipe(fd, LLDB_INVALID_PIPE);
124+
size_t num_bytes;
125+
Status error =
126+
socket_pipe.ReadWithTimeout(&protocol_info, sizeof(protocol_info),
127+
std::chrono::seconds(10), num_bytes);
128+
if (error.Fail())
129+
return error;
130+
if (num_bytes != sizeof(protocol_info)) {
131+
return Status(
132+
"socket_pipe.ReadWithTimeout(WSAPROTOCOL_INFO) failed: % d bytes",
133+
num_bytes);
134+
}
135+
}
136+
socket = ::WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
137+
FROM_PROTOCOL_INFO, &protocol_info, 0, 0);
138+
if (socket == INVALID_SOCKET) {
139+
return Status("WSASocket(FROM_PROTOCOL_INFO) failed: error %d",
140+
::WSAGetLastError());
141+
}
142+
return Status();
143+
#else
144+
socket = fd;
145+
return Status();
146+
#endif
147+
}
148+
73149
struct SocketScheme {
74150
const char *m_scheme;
75151
const Socket::SocketProtocol m_protocol;

lldb/tools/lldb-server/lldb-platform.cpp

+14-112
Original file line numberDiff line numberDiff line change
@@ -47,108 +47,6 @@ using namespace llvm;
4747

4848
// option descriptors for getopt_long_only()
4949

50-
#ifdef _WIN32
51-
typedef pipe_t shared_fd_t;
52-
const shared_fd_t kInvalidSharedFD = LLDB_INVALID_PIPE;
53-
#else
54-
typedef NativeSocket shared_fd_t;
55-
const shared_fd_t kInvalidSharedFD = Socket::kInvalidSocketValue;
56-
#endif
57-
58-
class SharedSocket {
59-
public:
60-
SharedSocket(Connection *conn, Status &error) {
61-
m_fd = kInvalidSharedFD;
62-
63-
const Socket *socket =
64-
static_cast<const Socket *>(conn->GetReadObject().get());
65-
if (socket == nullptr) {
66-
error = Status("invalid conn socket");
67-
return;
68-
}
69-
70-
#ifdef _WIN32
71-
m_socket = socket->GetNativeSocket();
72-
73-
// Create a pipe to transfer WSAPROTOCOL_INFO to the child process.
74-
error = m_socket_pipe.CreateNew(true);
75-
if (error.Fail())
76-
return;
77-
78-
m_fd = m_socket_pipe.GetReadPipe();
79-
#else
80-
m_fd = socket->GetNativeSocket();
81-
error = Status();
82-
#endif
83-
}
84-
85-
shared_fd_t GetSendableFD() { return m_fd; }
86-
87-
Status CompleteSending(lldb::pid_t child_pid) {
88-
#ifdef _WIN32
89-
// Transfer WSAPROTOCOL_INFO to the child process.
90-
m_socket_pipe.CloseReadFileDescriptor();
91-
92-
WSAPROTOCOL_INFO protocol_info;
93-
if (::WSADuplicateSocket(m_socket, child_pid, &protocol_info) ==
94-
SOCKET_ERROR) {
95-
int last_error = ::WSAGetLastError();
96-
return Status("WSADuplicateSocket() failed, error: %d", last_error);
97-
}
98-
99-
size_t num_bytes;
100-
Status error =
101-
m_socket_pipe.WriteWithTimeout(&protocol_info, sizeof(protocol_info),
102-
std::chrono::seconds(10), num_bytes);
103-
if (error.Fail())
104-
return error;
105-
if (num_bytes != sizeof(protocol_info))
106-
return Status("WriteWithTimeout(WSAPROTOCOL_INFO) failed: %d bytes",
107-
num_bytes);
108-
#endif
109-
return Status();
110-
}
111-
112-
static Status GetNativeSocket(shared_fd_t fd, NativeSocket &socket) {
113-
#ifdef _WIN32
114-
socket = Socket::kInvalidSocketValue;
115-
// Read WSAPROTOCOL_INFO from the parent process and create NativeSocket.
116-
WSAPROTOCOL_INFO protocol_info;
117-
{
118-
Pipe socket_pipe(fd, LLDB_INVALID_PIPE);
119-
size_t num_bytes;
120-
Status error =
121-
socket_pipe.ReadWithTimeout(&protocol_info, sizeof(protocol_info),
122-
std::chrono::seconds(10), num_bytes);
123-
if (error.Fail())
124-
return error;
125-
if (num_bytes != sizeof(protocol_info)) {
126-
return Status(
127-
"socket_pipe.ReadWithTimeout(WSAPROTOCOL_INFO) failed: % d bytes",
128-
num_bytes);
129-
}
130-
}
131-
socket = ::WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
132-
FROM_PROTOCOL_INFO, &protocol_info, 0, 0);
133-
if (socket == INVALID_SOCKET) {
134-
return Status("WSASocket(FROM_PROTOCOL_INFO) failed: error %d",
135-
::WSAGetLastError());
136-
}
137-
return Status();
138-
#else
139-
socket = fd;
140-
return Status();
141-
#endif
142-
}
143-
144-
private:
145-
#ifdef _WIN32
146-
Pipe m_socket_pipe;
147-
NativeSocket m_socket;
148-
#endif
149-
shared_fd_t m_fd;
150-
};
151-
15250
static int g_debug = 0;
15351
static int g_verbose = 0;
15452
static int g_server = 0;
@@ -259,13 +157,13 @@ static void spawn_process_reaped(lldb::pid_t pid, int signal, int status) {
259157
gdbserver_portmap.FreePortForProcess(pid);
260158
}
261159

262-
static Status spawn_process(const char *progname, Connection *conn,
160+
static Status spawn_process(const char *progname, const Socket *conn_socket,
263161
uint16_t gdb_port, uint16_t port_offset,
264162
const lldb_private::Args &args,
265163
const std::string &log_file,
266164
const StringRef log_channels) {
267165
Status error;
268-
SharedSocket shared_socket(conn, error);
166+
SharedSocket shared_socket(conn_socket, error);
269167
if (error.Fail())
270168
return error;
271169

@@ -363,7 +261,7 @@ int main_platform(int argc, char *argv[]) {
363261
StringRef
364262
log_channels; // e.g. "lldb process threads:gdb-remote default:linux all"
365263

366-
shared_fd_t fd = kInvalidSharedFD;
264+
shared_fd_t fd = SharedSocket::kInvalidFD;
367265

368266
int min_gdbserver_port = 0;
369267
int max_gdbserver_port = 0;
@@ -480,7 +378,7 @@ int main_platform(int argc, char *argv[]) {
480378
}
481379

482380
// Print usage and exit if no listening port is specified.
483-
if (listen_host_port.empty() && fd == kInvalidSharedFD)
381+
if (listen_host_port.empty() && fd == SharedSocket::kInvalidFD)
484382
show_usage = true;
485383

486384
if (show_usage || option_error) {
@@ -494,7 +392,7 @@ int main_platform(int argc, char *argv[]) {
494392
lldb_private::Args inferior_arguments;
495393
inferior_arguments.SetArguments(argc, const_cast<const char **>(argv));
496394

497-
if (fd != kInvalidSharedFD) {
395+
if (fd != SharedSocket::kInvalidFD) {
498396
// Child process will handle the connection and exit.
499397
Log *log = GetLog(LLDBLog::Platform);
500398
if (!listen_host_port.empty()) {
@@ -510,13 +408,14 @@ int main_platform(int argc, char *argv[]) {
510408
return socket_error;
511409
}
512410

513-
Connection *conn =
514-
new ConnectionFileDescriptor(new TCPSocket(socket, true, false));
515411
GDBRemoteCommunicationServerPlatform platform(Socket::ProtocolTcp, "tcp");
516412
if (port_offset > 0)
517413
platform.SetPortOffset(port_offset);
518414
platform.SetPortMap(std::move(gdbserver_portmap));
519-
platform.SetConnection(std::unique_ptr<Connection>(conn));
415+
platform.SetConnection(
416+
std::unique_ptr<Connection>(new ConnectionFileDescriptor(
417+
new TCPSocket(socket, /*should_close=*/true,
418+
/*child_processes_inherit=*/false))));
520419
client_handle(platform, inferior_arguments);
521420
return 0;
522421
}
@@ -578,8 +477,11 @@ int main_platform(int argc, char *argv[]) {
578477
fprintf(stderr,
579478
"no available gdbserver port for connection - dropping...\n");
580479
} else {
581-
error = spawn_process(progname, conn, *available_port, port_offset,
582-
inferior_arguments, log_file, log_channels);
480+
const Socket *conn_socket =
481+
static_cast<const Socket *>(conn->GetReadObject().get());
482+
error =
483+
spawn_process(progname, conn_socket, *available_port, port_offset,
484+
inferior_arguments, log_file, log_channels);
583485
if (error.Fail()) {
584486
{
585487

0 commit comments

Comments
 (0)