[Lldb-commits] [lldb] 0494484 - [NFC][lldb] Split DomainSocket into a base + posix/windows impls (#205864)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Jun 26 09:57:34 PDT 2026
Author: Charles Zablit
Date: 2026-06-26T17:57:29+01:00
New Revision: 049448403c7bfd140a212aefe3c422f3cad810ce
URL: https://github.com/llvm/llvm-project/commit/049448403c7bfd140a212aefe3c422f3cad810ce
DIFF: https://github.com/llvm/llvm-project/commit/049448403c7bfd140a212aefe3c422f3cad810ce.diff
LOG: [NFC][lldb] Split DomainSocket into a base + posix/windows impls (#205864)
Prepares for `AF_UNIX` domain-socket support on Windows by separating
the cross-platform socket logic from the one platform-specific
operation.
Every domain-socket operation is identical on POSIX and Windows (via
`<afunix.h>`), so it now lives in a single base class
`DomainSocket`. The one operation that is different is `CreatePair()`.
It lives in `DomainSocketPosix` / `DomainSocketWindows`. It's selected
for the host as `DomainSocketPlatform` through
`lldb/Host/DomainSocket.h`.
This is an NFC patch: POSIX behavior is unchanged, and while the shared
code now also compiles on Windows it stays unreachable there. A
follow-up commit enables it.
rdar://180736036
Added:
lldb/include/lldb/Host/DomainSocket.h
lldb/include/lldb/Host/common/DomainSocket.h
lldb/include/lldb/Host/posix/DomainSocketPosix.h
lldb/include/lldb/Host/windows/DomainSocketWindows.h
lldb/source/Host/common/DomainSocket.cpp
lldb/source/Host/posix/DomainSocketPosix.cpp
lldb/source/Host/windows/DomainSocketWindows.cpp
Modified:
lldb/include/lldb/Host/linux/AbstractSocket.h
lldb/source/Host/CMakeLists.txt
lldb/source/Host/common/Socket.cpp
lldb/tools/lldb-server/lldb-platform.cpp
lldb/unittests/TestingSupport/Host/SocketTestUtilities.h
Removed:
lldb/include/lldb/Host/posix/DomainSocket.h
lldb/source/Host/posix/DomainSocket.cpp
################################################################################
diff --git a/lldb/include/lldb/Host/DomainSocket.h b/lldb/include/lldb/Host/DomainSocket.h
new file mode 100644
index 0000000000000..d3e20c9b0ab3c
--- /dev/null
+++ b/lldb/include/lldb/Host/DomainSocket.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_HOST_DOMAINSOCKET_H
+#define LLDB_HOST_DOMAINSOCKET_H
+
+#include "lldb/Host/common/DomainSocket.h"
+
+#if defined(_WIN32)
+#include "lldb/Host/windows/DomainSocketWindows.h"
+#else
+#include "lldb/Host/posix/DomainSocketPosix.h"
+#endif
+
+namespace lldb_private {
+
+#if defined(_WIN32)
+using DomainSocketPlatform = DomainSocketWindows;
+#else
+using DomainSocketPlatform = DomainSocketPosix;
+#endif
+
+} // namespace lldb_private
+
+#endif // LLDB_HOST_DOMAINSOCKET_H
diff --git a/lldb/include/lldb/Host/posix/DomainSocket.h b/lldb/include/lldb/Host/common/DomainSocket.h
similarity index 69%
rename from lldb/include/lldb/Host/posix/DomainSocket.h
rename to lldb/include/lldb/Host/common/DomainSocket.h
index cfb31922367c5..4d2b657cf88e4 100644
--- a/lldb/include/lldb/Host/posix/DomainSocket.h
+++ b/lldb/include/lldb/Host/common/DomainSocket.h
@@ -1,4 +1,4 @@
-//===-- DomainSocket.h ------------------------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,14 +6,22 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_HOST_POSIX_DOMAINSOCKET_H
-#define LLDB_HOST_POSIX_DOMAINSOCKET_H
+#ifndef LLDB_HOST_COMMON_DOMAINSOCKET_H
+#define LLDB_HOST_COMMON_DOMAINSOCKET_H
#include "lldb/Host/Socket.h"
#include <string>
#include <vector>
namespace lldb_private {
+
+/// Cross-platform AF_UNIX domain-socket logic.
+///
+/// Every operation on a domain socket (connect, listen, accept, name
+/// lookup) is identical on POSIX and Windows, so it all lives here. The only
+/// operation which
diff ers between platforms is the CreatePair() factory: POSIX
+/// has socketpair(2) while Windows must emulate it. That factory therefore
+/// lives in the DomainSocketPosix / DomainSocketWindows implementation classes.
class DomainSocket : public Socket {
public:
DomainSocket(NativeSocket socket, bool should_close);
@@ -21,7 +29,6 @@ class DomainSocket : public Socket {
using Pair =
std::pair<std::unique_ptr<DomainSocket>, std::unique_ptr<DomainSocket>>;
- static llvm::Expected<Pair> CreatePair();
Status Connect(llvm::StringRef name) override;
Status Listen(llvm::StringRef name, int backlog) override;
@@ -49,6 +56,6 @@ class DomainSocket : public Socket {
private:
DomainSocket(NativeSocket socket, const DomainSocket &listen_socket);
};
-}
+} // namespace lldb_private
-#endif // LLDB_HOST_POSIX_DOMAINSOCKET_H
+#endif // LLDB_HOST_COMMON_DOMAINSOCKET_H
diff --git a/lldb/include/lldb/Host/linux/AbstractSocket.h b/lldb/include/lldb/Host/linux/AbstractSocket.h
index c6a0e2f8af63b..3e1b228432141 100644
--- a/lldb/include/lldb/Host/linux/AbstractSocket.h
+++ b/lldb/include/lldb/Host/linux/AbstractSocket.h
@@ -9,7 +9,7 @@
#ifndef liblldb_AbstractSocket_h_
#define liblldb_AbstractSocket_h_
-#include "lldb/Host/posix/DomainSocket.h"
+#include "lldb/Host/common/DomainSocket.h"
namespace lldb_private {
class AbstractSocket : public DomainSocket {
diff --git a/lldb/include/lldb/Host/posix/DomainSocketPosix.h b/lldb/include/lldb/Host/posix/DomainSocketPosix.h
new file mode 100644
index 0000000000000..1e37cd09cb9ec
--- /dev/null
+++ b/lldb/include/lldb/Host/posix/DomainSocketPosix.h
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_HOST_POSIX_DOMAINSOCKETPOSIX_H
+#define LLDB_HOST_POSIX_DOMAINSOCKETPOSIX_H
+
+#include "lldb/Host/common/DomainSocket.h"
+
+namespace lldb_private {
+
+/// \class DomainSocketPosix DomainSocketPosix.h
+/// "lldb/Host/posix/DomainSocketPosix.h"
+/// POSIX implementation of the platform-specific parts of DomainSocket.
+class DomainSocketPosix : public DomainSocket {
+public:
+ using DomainSocket::DomainSocket;
+
+ /// Create a connected pair of domain sockets using socketpair(2).
+ static llvm::Expected<Pair> CreatePair();
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_HOST_POSIX_DOMAINSOCKETPOSIX_H
diff --git a/lldb/include/lldb/Host/windows/DomainSocketWindows.h b/lldb/include/lldb/Host/windows/DomainSocketWindows.h
new file mode 100644
index 0000000000000..3b8f39bd12154
--- /dev/null
+++ b/lldb/include/lldb/Host/windows/DomainSocketWindows.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_HOST_WINDOWS_DOMAINSOCKETWINDOWS_H
+#define LLDB_HOST_WINDOWS_DOMAINSOCKETWINDOWS_H
+
+#include "lldb/Host/common/DomainSocket.h"
+
+namespace lldb_private {
+
+/// \class DomainSocketWindows DomainSocketWindows.h
+/// "lldb/Host/windows/DomainSocketWindows.h"
+/// Windows implementation of the platform-specific parts of DomainSocket.
+class DomainSocketWindows : public DomainSocket {
+public:
+ using DomainSocket::DomainSocket;
+
+ /// Create a connected pair of domain sockets. Windows has no socketpair(2),
+ /// so this is emulated with a transient listening socket.
+ static llvm::Expected<Pair> CreatePair();
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_HOST_WINDOWS_DOMAINSOCKETWINDOWS_H
diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt
index 28c639ee38215..57a833af97184 100644
--- a/lldb/source/Host/CMakeLists.txt
+++ b/lldb/source/Host/CMakeLists.txt
@@ -19,6 +19,7 @@ endmacro()
add_host_subdirectory(common
common/ConPTYUtils.cpp
common/DiagnosticsRendering.cpp
+ common/DomainSocket.cpp
common/FileAction.cpp
common/FileCache.cpp
common/File.cpp
@@ -79,6 +80,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
add_host_subdirectory(windows
windows/ConnectionConPTYWindows.cpp
windows/ConnectionGenericFileWindows.cpp
+ windows/DomainSocketWindows.cpp
windows/FileSystem.cpp
windows/FileWindows.cpp
windows/Host.cpp
@@ -100,7 +102,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
endif()
else()
add_host_subdirectory(posix
- posix/DomainSocket.cpp
+ posix/DomainSocketPosix.cpp
posix/FilePosix.cpp
posix/FileSystemPosix.cpp
posix/HostInfoPosix.cpp
diff --git a/lldb/source/Host/posix/DomainSocket.cpp b/lldb/source/Host/common/DomainSocket.cpp
similarity index 79%
rename from lldb/source/Host/posix/DomainSocket.cpp
rename to lldb/source/Host/common/DomainSocket.cpp
index 4f08c372d43cf..988b8238a3cce 100644
--- a/lldb/source/Host/posix/DomainSocket.cpp
+++ b/lldb/source/Host/common/DomainSocket.cpp
@@ -1,4 +1,4 @@
-//===-- DomainSocket.cpp --------------------------------------------------===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Host/posix/DomainSocket.h"
+#include "lldb/Host/common/DomainSocket.h"
#include "lldb/Utility/LLDBLog.h"
#ifdef __linux__
#include <lldb/Host/linux/AbstractSocket.h>
@@ -17,10 +17,14 @@
#include "llvm/Support/FileSystem.h"
#include <cstddef>
-#include <fcntl.h>
#include <memory>
+
+#ifdef _WIN32
+#include <afunix.h>
+#else
#include <sys/socket.h>
#include <sys/un.h>
+#endif
using namespace lldb;
using namespace lldb_private;
@@ -38,14 +42,10 @@ static bool SetSockAddr(llvm::StringRef name, const size_t name_offset,
memcpy(saddr_un->sun_path + name_offset, name.data(), name.size());
- // For domain sockets we can use SUN_LEN in order to calculate size of
- // sockaddr_un, but for abstract sockets we have to calculate size manually
- // because of leading null symbol.
- if (name_offset == 0)
- saddr_un_len = SUN_LEN(saddr_un);
- else
- saddr_un_len =
- offsetof(struct sockaddr_un, sun_path) + name_offset + name.size();
+ // Compute the address length explicitly rather than via SUN_LEN: that macro
+ // is not available on Windows.
+ saddr_un_len =
+ offsetof(struct sockaddr_un, sun_path) + name_offset + name.size();
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
defined(__OpenBSD__)
@@ -78,41 +78,6 @@ DomainSocket::DomainSocket(SocketProtocol protocol, NativeSocket socket,
m_socket = socket;
}
-llvm::Expected<DomainSocket::Pair> DomainSocket::CreatePair() {
- int sockets[2];
- int type = SOCK_STREAM;
-#ifdef SOCK_CLOEXEC
- type |= SOCK_CLOEXEC;
-#endif
- if (socketpair(AF_UNIX, type, 0, sockets) == -1)
- return llvm::errorCodeToError(llvm::errnoAsErrorCode());
-
-#ifndef SOCK_CLOEXEC
- for (int s : sockets) {
- int r = fcntl(s, F_SETFD, FD_CLOEXEC | fcntl(s, F_GETFD));
- assert(r == 0);
- (void)r;
- }
-#endif
-
-#if defined(SO_NOSIGPIPE)
- Log *log = GetLog(LLDBLog::Host);
- if (Socket::SetOption(sockets[0], SOL_SOCKET, SO_NOSIGPIPE, 1) == -1)
- LLDB_LOG(log, "failed to set NO_SIGPIPE on fd {0}: {1}", sockets[0],
- llvm::sys::StrError());
- if (Socket::SetOption(sockets[1], SOL_SOCKET, SO_NOSIGPIPE, 1) == -1)
- LLDB_LOG(log, "failed to set NO_SIGPIPE on fd {0}: {1}", sockets[1],
- llvm::sys::StrError());
-#endif
-
- return Pair(std::unique_ptr<DomainSocket>(
- new DomainSocket(ProtocolUnixDomain, sockets[0],
- /*should_close=*/true)),
- std::unique_ptr<DomainSocket>(
- new DomainSocket(ProtocolUnixDomain, sockets[1],
- /*should_close=*/true)));
-}
-
Status DomainSocket::Connect(llvm::StringRef name) {
sockaddr_un saddr_un;
socklen_t saddr_un_len;
diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp
index 810d63fc0390d..c0247509df1c1 100644
--- a/lldb/source/Host/common/Socket.cpp
+++ b/lldb/source/Host/common/Socket.cpp
@@ -24,9 +24,9 @@
#include "llvm/Support/Regex.h"
#include "llvm/Support/WindowsError.h"
-#if LLDB_ENABLE_POSIX
-#include "lldb/Host/posix/DomainSocket.h"
+#include "lldb/Host/DomainSocket.h"
+#if LLDB_ENABLE_POSIX
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
@@ -241,10 +241,17 @@ Socket::CreatePair(std::optional<SocketProtocol> protocol) {
switch (protocol.value_or(kBestProtocol)) {
case ProtocolTcp:
return TCPSocket::CreatePair();
-#if LLDB_ENABLE_POSIX
case ProtocolUnixDomain:
+#if LLDB_ENABLE_POSIX
+ return DomainSocketPlatform::CreatePair();
+#else
+ return llvm::createStringError("unsupported protocol");
+#endif
case ProtocolUnixAbstract:
- return DomainSocket::CreatePair();
+#if LLDB_ENABLE_POSIX
+ return DomainSocketPlatform::CreatePair();
+#else
+ return llvm::createStringError("unsupported protocol");
#endif
default:
return llvm::createStringError("unsupported protocol");
diff --git a/lldb/source/Host/posix/DomainSocketPosix.cpp b/lldb/source/Host/posix/DomainSocketPosix.cpp
new file mode 100644
index 0000000000000..77ea6c593bb38
--- /dev/null
+++ b/lldb/source/Host/posix/DomainSocketPosix.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "lldb/Host/posix/DomainSocketPosix.h"
+#include "lldb/Utility/LLDBLog.h"
+
+#include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
+
+#include <cassert>
+#include <fcntl.h>
+#include <memory>
+#include <sys/socket.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+llvm::Expected<DomainSocket::Pair> DomainSocketPosix::CreatePair() {
+ int sockets[2];
+ int type = SOCK_STREAM;
+#ifdef SOCK_CLOEXEC
+ type |= SOCK_CLOEXEC;
+#endif
+ if (socketpair(AF_UNIX, type, 0, sockets) == -1)
+ return llvm::errorCodeToError(llvm::errnoAsErrorCode());
+
+#ifndef SOCK_CLOEXEC
+ for (int s : sockets) {
+ int r = fcntl(s, F_SETFD, FD_CLOEXEC | fcntl(s, F_GETFD));
+ assert(r == 0);
+ (void)r;
+ }
+#endif
+
+#if defined(SO_NOSIGPIPE)
+ Log *log = GetLog(LLDBLog::Host);
+ if (Socket::SetOption(sockets[0], SOL_SOCKET, SO_NOSIGPIPE, 1) == -1)
+ LLDB_LOG(log, "failed to set NO_SIGPIPE on fd {0}: {1}", sockets[0],
+ llvm::sys::StrError());
+ if (Socket::SetOption(sockets[1], SOL_SOCKET, SO_NOSIGPIPE, 1) == -1)
+ LLDB_LOG(log, "failed to set NO_SIGPIPE on fd {0}: {1}", sockets[1],
+ llvm::sys::StrError());
+#endif
+
+ return Pair(std::unique_ptr<DomainSocket>(new DomainSocketPosix(
+ ProtocolUnixDomain, sockets[0], /*should_close=*/true)),
+ std::unique_ptr<DomainSocket>(new DomainSocketPosix(
+ ProtocolUnixDomain, sockets[1], /*should_close=*/true)));
+}
diff --git a/lldb/source/Host/windows/DomainSocketWindows.cpp b/lldb/source/Host/windows/DomainSocketWindows.cpp
new file mode 100644
index 0000000000000..eddc7a955ad38
--- /dev/null
+++ b/lldb/source/Host/windows/DomainSocketWindows.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "lldb/Host/windows/DomainSocketWindows.h"
+
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+#include <chrono>
+#include <memory>
+
+using namespace lldb;
+using namespace lldb_private;
+
+llvm::Expected<DomainSocket::Pair> DomainSocketWindows::CreatePair() {
+ // Windows has no socketpair(). Emulate it the same way TCPSocket::CreatePair
+ // does for loopback TCP: bind a listener to a unique temporary path, connect
+ // a client to it, and accept. AF_UNIX SOCK_STREAM connect() completes once
+ // the connection is queued (backlog >= 1), so a single thread can connect
+ // and then accept without deadlocking.
+ llvm::SmallString<128> model;
+ llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/true, model);
+ llvm::sys::path::append(model, "lldb-domain-socketpair-%%%%%%%%.sock");
+ llvm::SmallString<128> path;
+ llvm::sys::fs::createUniquePath(model, path, /*MakeAbsolute=*/false);
+ auto remove_file =
+ llvm::make_scope_exit([&] { llvm::sys::fs::remove(path); });
+
+ auto listen_socket =
+ std::make_unique<DomainSocketWindows>(/*should_close=*/true);
+ if (Status error = listen_socket->Listen(path, /*backlog=*/1); error.Fail())
+ return error.takeError();
+
+ auto connect_socket =
+ std::make_unique<DomainSocketWindows>(/*should_close=*/true);
+ if (Status error = connect_socket->Connect(path); error.Fail())
+ return error.takeError();
+
+ // The connection is already queued, so a short timeout is sufficient.
+ Socket *accept_socket = nullptr;
+ if (Status error =
+ listen_socket->Accept(std::chrono::seconds(1), accept_socket);
+ error.Fail())
+ return error.takeError();
+
+ return Pair(std::move(connect_socket),
+ std::unique_ptr<DomainSocket>(
+ static_cast<DomainSocket *>(accept_socket)));
+}
diff --git a/lldb/tools/lldb-server/lldb-platform.cpp b/lldb/tools/lldb-server/lldb-platform.cpp
index ec2ef053241ca..b1f03b36c578f 100644
--- a/lldb/tools/lldb-server/lldb-platform.cpp
+++ b/lldb/tools/lldb-server/lldb-platform.cpp
@@ -39,10 +39,8 @@
#include "lldb/Host/MainLoop.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/Socket.h"
+#include "lldb/Host/common/DomainSocket.h"
#include "lldb/Host/common/TCPSocket.h"
-#if LLDB_ENABLE_POSIX
-#include "lldb/Host/posix/DomainSocket.h"
-#endif
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Status.h"
diff --git a/lldb/unittests/TestingSupport/Host/SocketTestUtilities.h b/lldb/unittests/TestingSupport/Host/SocketTestUtilities.h
index a7c9aee162e65..a03baf190dd33 100644
--- a/lldb/unittests/TestingSupport/Host/SocketTestUtilities.h
+++ b/lldb/unittests/TestingSupport/Host/SocketTestUtilities.h
@@ -22,7 +22,7 @@
#include "llvm/Testing/Support/Error.h"
#if LLDB_ENABLE_POSIX
-#include "lldb/Host/posix/DomainSocket.h"
+#include "lldb/Host/common/DomainSocket.h"
#endif
namespace lldb_private {
More information about the lldb-commits
mailing list