[Lldb-commits] [lldb] 488eeb3 - Fix connecting via abstract socket (#136466)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Apr 25 14:11:23 PDT 2025
Author: Emre Kultursay
Date: 2025-04-25T14:11:19-07:00
New Revision: 488eeb3ae508221f8e476bbc9d2e9f014542862e
URL: https://github.com/llvm/llvm-project/commit/488eeb3ae508221f8e476bbc9d2e9f014542862e
DIFF: https://github.com/llvm/llvm-project/commit/488eeb3ae508221f8e476bbc9d2e9f014542862e.diff
LOG: Fix connecting via abstract socket (#136466)
Commit 82ee31f and Commit 2e893124 added socket sharing, but only for
unix domain sockets. That broke Android, which uses unix-abstract
sockets.
Added:
Modified:
lldb/include/lldb/Host/linux/AbstractSocket.h
lldb/include/lldb/Host/posix/DomainSocket.h
lldb/source/Host/linux/AbstractSocket.cpp
lldb/source/Host/posix/DomainSocket.cpp
lldb/tools/lldb-server/lldb-platform.cpp
lldb/unittests/Host/SocketTest.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Host/linux/AbstractSocket.h b/lldb/include/lldb/Host/linux/AbstractSocket.h
index accfd01457a5e..c6a0e2f8af63b 100644
--- a/lldb/include/lldb/Host/linux/AbstractSocket.h
+++ b/lldb/include/lldb/Host/linux/AbstractSocket.h
@@ -15,6 +15,7 @@ namespace lldb_private {
class AbstractSocket : public DomainSocket {
public:
AbstractSocket();
+ AbstractSocket(NativeSocket socket, bool should_close);
protected:
size_t GetNameOffset() const override;
diff --git a/lldb/include/lldb/Host/posix/DomainSocket.h b/lldb/include/lldb/Host/posix/DomainSocket.h
index 3dbe6206da2c5..a840d474429ec 100644
--- a/lldb/include/lldb/Host/posix/DomainSocket.h
+++ b/lldb/include/lldb/Host/posix/DomainSocket.h
@@ -31,8 +31,12 @@ class DomainSocket : public Socket {
std::vector<std::string> GetListeningConnectionURI() const override;
+ static llvm::Expected<std::unique_ptr<DomainSocket>>
+ FromBoundNativeSocket(NativeSocket sockfd, bool should_close);
+
protected:
DomainSocket(SocketProtocol protocol);
+ DomainSocket(SocketProtocol protocol, NativeSocket socket, bool should_close);
virtual size_t GetNameOffset() const;
virtual void DeleteSocketFile(llvm::StringRef name);
diff --git a/lldb/source/Host/linux/AbstractSocket.cpp b/lldb/source/Host/linux/AbstractSocket.cpp
index 8393a80e86e72..681aa2d1ebc72 100644
--- a/lldb/source/Host/linux/AbstractSocket.cpp
+++ b/lldb/source/Host/linux/AbstractSocket.cpp
@@ -15,6 +15,9 @@ using namespace lldb_private;
AbstractSocket::AbstractSocket() : DomainSocket(ProtocolUnixAbstract) {}
+AbstractSocket::AbstractSocket(NativeSocket socket, bool should_close)
+ : DomainSocket(ProtocolUnixAbstract, socket, should_close) {}
+
size_t AbstractSocket::GetNameOffset() const { return 1; }
void AbstractSocket::DeleteSocketFile(llvm::StringRef name) {}
diff --git a/lldb/source/Host/posix/DomainSocket.cpp b/lldb/source/Host/posix/DomainSocket.cpp
index 6c490cdda47ed..4f76e0c16d4c7 100644
--- a/lldb/source/Host/posix/DomainSocket.cpp
+++ b/lldb/source/Host/posix/DomainSocket.cpp
@@ -8,6 +8,9 @@
#include "lldb/Host/posix/DomainSocket.h"
#include "lldb/Utility/LLDBLog.h"
+#ifdef __linux__
+#include <lldb/Host/linux/AbstractSocket.h>
+#endif
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
@@ -67,6 +70,12 @@ DomainSocket::DomainSocket(NativeSocket socket,
m_socket = socket;
}
+DomainSocket::DomainSocket(SocketProtocol protocol, NativeSocket socket,
+ bool should_close)
+ : Socket(protocol, should_close) {
+ m_socket = socket;
+}
+
Status DomainSocket::Connect(llvm::StringRef name) {
sockaddr_un saddr_un;
socklen_t saddr_un_len;
@@ -182,3 +191,20 @@ std::vector<std::string> DomainSocket::GetListeningConnectionURI() const {
return {llvm::formatv("unix-connect://{0}", addr.sun_path)};
}
+
+llvm::Expected<std::unique_ptr<DomainSocket>>
+DomainSocket::FromBoundNativeSocket(NativeSocket sockfd, bool should_close) {
+ // Check if fd represents domain socket or abstract socket.
+ struct sockaddr_un addr;
+ socklen_t addr_len = sizeof(addr);
+ if (getsockname(sockfd, (struct sockaddr *)&addr, &addr_len) == -1)
+ return llvm::createStringError("not a socket or error occurred");
+ if (addr.sun_family != AF_UNIX)
+ return llvm::createStringError("Bad socket type");
+#ifdef __linux__
+ if (addr_len > offsetof(struct sockaddr_un, sun_path) &&
+ addr.sun_path[0] == '\0')
+ return std::make_unique<AbstractSocket>(sockfd, should_close);
+#endif
+ return std::make_unique<DomainSocket>(sockfd, should_close);
+}
diff --git a/lldb/tools/lldb-server/lldb-platform.cpp b/lldb/tools/lldb-server/lldb-platform.cpp
index 23d36ffb4cb66..b9a85370d649c 100644
--- a/lldb/tools/lldb-server/lldb-platform.cpp
+++ b/lldb/tools/lldb-server/lldb-platform.cpp
@@ -455,15 +455,9 @@ int main_platform(int argc, char *argv[]) {
lldb_private::Args inferior_arguments;
inferior_arguments.SetArguments(argc, const_cast<const char **>(argv));
- Socket::SocketProtocol protocol = Socket::ProtocolUnixDomain;
-
+ Log *log = GetLog(LLDBLog::Platform);
if (fd != SharedSocket::kInvalidFD) {
// Child process will handle the connection and exit.
- if (gdbserver_port)
- protocol = Socket::ProtocolTcp;
-
- Log *log = GetLog(LLDBLog::Platform);
-
NativeSocket sockfd;
error = SharedSocket::GetNativeSocket(fd, sockfd);
if (error.Fail()) {
@@ -471,21 +465,24 @@ int main_platform(int argc, char *argv[]) {
return socket_error;
}
- GDBRemoteCommunicationServerPlatform platform(protocol, gdbserver_port);
- Socket *socket;
- if (protocol == Socket::ProtocolTcp)
- socket = new TCPSocket(sockfd, /*should_close=*/true);
- else {
-#if LLDB_ENABLE_POSIX
- socket = new DomainSocket(sockfd, /*should_close=*/true);
-#else
- WithColor::error() << "lldb-platform child: Unix domain sockets are not "
- "supported on this platform.";
- return socket_error;
-#endif
+ std::unique_ptr<Socket> socket;
+ if (gdbserver_port) {
+ socket = std::make_unique<TCPSocket>(sockfd, /*should_close=*/true);
+ } else {
+ llvm::Expected<std::unique_ptr<DomainSocket>> domain_socket =
+ DomainSocket::FromBoundNativeSocket(sockfd, /*should_close=*/true);
+ if (!domain_socket) {
+ LLDB_LOG_ERROR(log, domain_socket.takeError(),
+ "Failed to create socket: {0}");
+ return socket_error;
+ }
+ socket = std::move(domain_socket.get());
}
- platform.SetConnection(
- std::unique_ptr<Connection>(new ConnectionFileDescriptor(socket)));
+
+ GDBRemoteCommunicationServerPlatform platform(socket->GetSocketProtocol(),
+ gdbserver_port);
+ platform.SetConnection(std::unique_ptr<Connection>(
+ new ConnectionFileDescriptor(socket.release())));
client_handle(platform, inferior_arguments);
return 0;
}
@@ -498,6 +495,7 @@ int main_platform(int argc, char *argv[]) {
return 1;
}
+ Socket::SocketProtocol protocol = Socket::ProtocolUnixDomain;
std::string address;
std::string gdb_address;
uint16_t platform_port = 0;
diff --git a/lldb/unittests/Host/SocketTest.cpp b/lldb/unittests/Host/SocketTest.cpp
index 9cbf3e26b0883..5bfb48b52f7e7 100644
--- a/lldb/unittests/Host/SocketTest.cpp
+++ b/lldb/unittests/Host/SocketTest.cpp
@@ -15,6 +15,9 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <chrono>
+#if __linux__
+#include <lldb/Host/linux/AbstractSocket.h>
+#endif
using namespace lldb_private;
@@ -337,6 +340,47 @@ TEST_F(SocketTest, DomainGetConnectURI) {
EXPECT_EQ(socket_b_up->GetRemoteConnectionURI(), "");
}
+
+TEST_F(SocketTest, DomainSocketFromBoundNativeSocket) {
+ // Generate a name for the domain socket.
+ llvm::SmallString<64> name;
+ std::error_code EC = llvm::sys::fs::createUniqueDirectory(
+ "DomainSocketFromBoundNativeSocket", name);
+ ASSERT_FALSE(EC);
+ llvm::sys::path::append(name, "test");
+
+ DomainSocket socket(true);
+ Status error = socket.Listen(name, /*backlog=*/10);
+ ASSERT_THAT_ERROR(error.takeError(), llvm::Succeeded());
+ NativeSocket native_socket = socket.GetNativeSocket();
+
+ llvm::Expected<std::unique_ptr<DomainSocket>> sock =
+ DomainSocket::FromBoundNativeSocket(native_socket,
+ /*should_close=*/false);
+ ASSERT_THAT_EXPECTED(sock, llvm::Succeeded());
+ ASSERT_EQ(Socket::ProtocolUnixDomain, sock->get()->GetSocketProtocol());
+}
+#endif
+
+#if __linux__
+TEST_F(SocketTest, AbstractSocketFromBoundNativeSocket) {
+ // Generate a name for the abstract socket.
+ llvm::SmallString<100> name;
+ llvm::sys::fs::createUniquePath("AbstractSocketFromBoundNativeSocket", name,
+ true);
+ llvm::sys::path::append(name, "test");
+
+ AbstractSocket socket;
+ Status error = socket.Listen(name, /*backlog=*/10);
+ ASSERT_THAT_ERROR(error.takeError(), llvm::Succeeded());
+ NativeSocket native_socket = socket.GetNativeSocket();
+
+ llvm::Expected<std::unique_ptr<DomainSocket>> sock =
+ DomainSocket::FromBoundNativeSocket(native_socket,
+ /*should_close=*/false);
+ ASSERT_THAT_EXPECTED(sock, llvm::Succeeded());
+ ASSERT_EQ(Socket::ProtocolUnixAbstract, sock->get()->GetSocketProtocol());
+}
#endif
INSTANTIATE_TEST_SUITE_P(
More information about the lldb-commits
mailing list