aadsm created this revision.
aadsm added reviewers: labath, clayborg, xiaobai.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

My main goal here is to make lldb-server work with Android Studio.

This is currently not the case because lldb-server is started in platform mode 
listening on a domain socket. When Android Studio connects to it lldb-server 
crashes because even though it's listening on a domain socket as soon as it 
gets a connection it asserts that it's a TCP connection, which will obviously 
fails for any non-tcp connection.

To do this I came up with a new method called GetConnectURI() in Socket that 
returns the URI needed to connect to the connected portion of the socket.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D62089

Files:
  lldb/include/lldb/Host/Socket.h
  lldb/include/lldb/Host/common/TCPSocket.h
  lldb/include/lldb/Host/common/UDPSocket.h
  lldb/include/lldb/Host/posix/DomainSocket.h
  lldb/source/Host/common/TCPSocket.cpp
  lldb/source/Host/common/UDPSocket.cpp
  lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
  lldb/source/Host/posix/DomainSocket.cpp
  lldb/unittests/Host/SocketTest.cpp

Index: lldb/unittests/Host/SocketTest.cpp
===================================================================
--- lldb/unittests/Host/SocketTest.cpp
+++ lldb/unittests/Host/SocketTest.cpp
@@ -7,7 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "SocketTestUtilities.h"
+#include "lldb/Utility/UriParser.h"
 #include "gtest/gtest.h"
+#include <iostream>
 
 using namespace lldb_private;
 
@@ -147,3 +149,67 @@
   EXPECT_TRUE(socket_up->IsValid());
   EXPECT_NE(socket_up->GetLocalPortNumber(), 0);
 }
+
+TEST_F(SocketTest, TCPGetConnectURI) {
+  std::unique_ptr<TCPSocket> socket_a_up;
+  std::unique_ptr<TCPSocket> socket_b_up;
+  if (!IsAddressFamilySupported("127.0.0.1")) {
+    GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support.";
+    return;
+  }
+  CreateTCPConnectedSockets("127.0.0.1", &socket_a_up, &socket_b_up);
+
+  llvm::StringRef scheme;
+  llvm::StringRef hostname;
+  int port;
+  llvm::StringRef path;
+  EXPECT_TRUE(UriParser::Parse(socket_a_up->GetConnectURI(), scheme, hostname,
+                               port, path));
+  EXPECT_STREQ(scheme.str().c_str(), "connect");
+  EXPECT_EQ(port, socket_a_up->GetRemotePortNumber());
+}
+
+TEST_F(SocketTest, UDPGetConnectURI) {
+  std::unique_ptr<TCPSocket> socket_a_up;
+  std::unique_ptr<TCPSocket> socket_b_up;
+  if (!IsAddressFamilySupported("127.0.0.1")) {
+    GTEST_LOG_(WARNING) << "Skipping test due to missing IPv4 support.";
+    return;
+  }
+  Socket *socket;
+
+  bool child_processes_inherit = false;
+  auto error =
+      UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, socket);
+
+  llvm::StringRef scheme;
+  llvm::StringRef hostname;
+  int port;
+  llvm::StringRef path;
+  EXPECT_TRUE(
+      UriParser::Parse(socket->GetConnectURI(), scheme, hostname, port, path));
+  EXPECT_STREQ(scheme.str().c_str(), "udp");
+}
+
+#ifndef LLDB_DISABLE_POSIX
+TEST_F(SocketTest, DomainGetConnectURI) {
+  llvm::SmallString<64> Path;
+  std::error_code EC =
+      llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path);
+  ASSERT_FALSE(EC);
+  llvm::sys::path::append(Path, "test");
+
+  std::unique_ptr<DomainSocket> socket_a_up;
+  std::unique_ptr<DomainSocket> socket_b_up;
+  CreateDomainConnectedSockets(Path, &socket_a_up, &socket_b_up);
+
+  llvm::StringRef scheme;
+  llvm::StringRef hostname;
+  int port;
+  llvm::StringRef path;
+  EXPECT_TRUE(UriParser::Parse(socket_a_up->GetConnectURI(), scheme, hostname,
+                               port, path));
+  EXPECT_STREQ(scheme.str().c_str(), "unix-connect");
+  EXPECT_STREQ(path.str().c_str(), Path.c_str());
+}
+#endif
\ No newline at end of file
Index: lldb/source/Host/posix/DomainSocket.cpp
===================================================================
--- lldb/source/Host/posix/DomainSocket.cpp
+++ lldb/source/Host/posix/DomainSocket.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Host/posix/DomainSocket.h"
+#include "lldb/Utility/StreamString.h"
 
 #include "llvm/Support/Errno.h"
 #include "llvm/Support/FileSystem.h"
@@ -125,3 +126,29 @@
 void DomainSocket::DeleteSocketFile(llvm::StringRef name) {
   llvm::sys::fs::remove(name);
 }
+
+std::string DomainSocket::GetSocketName() const {
+  if (m_socket != kInvalidSocketValue) {
+    struct sockaddr_un saddr_un;
+    saddr_un.sun_family = AF_UNIX;
+    socklen_t sock_addr_len = sizeof(struct sockaddr_un);
+    if (::getpeername(m_socket, (struct sockaddr *)&saddr_un, &sock_addr_len) ==
+        0)
+      return std::string(saddr_un.sun_path + GetNameOffset(),
+                         sock_addr_len -
+                             offsetof(struct sockaddr_un, sun_path) -
+                             GetNameOffset());
+  }
+  return "";
+}
+
+std::string DomainSocket::GetConnectURI() const {
+  if (m_socket != kInvalidSocketValue) {
+    StreamString strm;
+    strm.Printf("%s://%s",
+                GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect",
+                GetSocketName().c_str());
+    return strm.GetString();
+  }
+  return "";
+}
Index: lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
===================================================================
--- lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -758,13 +758,7 @@
 }
 
 void ConnectionFileDescriptor::InitializeSocket(Socket *socket) {
-  assert(socket->GetSocketProtocol() == Socket::ProtocolTcp);
-  TCPSocket *tcp_socket = static_cast<TCPSocket *>(socket);
-
   m_write_sp.reset(socket);
   m_read_sp = m_write_sp;
-  StreamString strm;
-  strm.Printf("connect://[%s]:%u", tcp_socket->GetRemoteIPAddress().c_str(),
-              tcp_socket->GetRemotePortNumber());
-  m_uri = strm.GetString();
+  m_uri = socket->GetConnectURI();
 }
Index: lldb/source/Host/common/UDPSocket.cpp
===================================================================
--- lldb/source/Host/common/UDPSocket.cpp
+++ lldb/source/Host/common/UDPSocket.cpp
@@ -10,6 +10,7 @@
 
 #include "lldb/Host/Config.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
 
 #ifndef LLDB_DISABLE_POSIX
 #include <arpa/inet.h>
@@ -134,3 +135,13 @@
   error.Clear();
   return error;
 }
+
+std::string UDPSocket::GetConnectURI() const {
+  if (m_socket != kInvalidSocketValue) {
+    StreamString strm;
+    strm.Printf("udp://[%s]:%u", m_sockaddr.GetIPAddress().c_str(),
+                m_sockaddr.GetPort());
+    return strm.GetString();
+  }
+  return "";
+}
Index: lldb/source/Host/common/TCPSocket.cpp
===================================================================
--- lldb/source/Host/common/TCPSocket.cpp
+++ lldb/source/Host/common/TCPSocket.cpp
@@ -15,6 +15,7 @@
 #include "lldb/Host/Config.h"
 #include "lldb/Host/MainLoop.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
 
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Support/Errno.h"
@@ -118,6 +119,16 @@
   return "";
 }
 
+std::string TCPSocket::GetConnectURI() const {
+  if (m_socket != kInvalidSocketValue) {
+    StreamString strm;
+    strm.Printf("connect://[%s]:%u", GetRemoteIPAddress().c_str(),
+                GetRemotePortNumber());
+    return strm.GetString();
+  }
+  return "";
+};
+
 Status TCPSocket::CreateSocket(int domain) {
   Status error;
   if (IsValid())
Index: lldb/include/lldb/Host/posix/DomainSocket.h
===================================================================
--- lldb/include/lldb/Host/posix/DomainSocket.h
+++ lldb/include/lldb/Host/posix/DomainSocket.h
@@ -20,11 +20,14 @@
   Status Listen(llvm::StringRef name, int backlog) override;
   Status Accept(Socket *&socket) override;
 
+  std::string GetConnectURI() const override;
+
 protected:
   DomainSocket(SocketProtocol protocol, bool child_processes_inherit);
 
   virtual size_t GetNameOffset() const;
   virtual void DeleteSocketFile(llvm::StringRef name);
+  std::string GetSocketName() const;
 
 private:
   DomainSocket(NativeSocket socket, const DomainSocket &listen_socket);
Index: lldb/include/lldb/Host/common/UDPSocket.h
===================================================================
--- lldb/include/lldb/Host/common/UDPSocket.h
+++ lldb/include/lldb/Host/common/UDPSocket.h
@@ -19,6 +19,8 @@
   static Status Connect(llvm::StringRef name, bool child_processes_inherit,
                         Socket *&socket);
 
+  std::string GetConnectURI() const override;
+
 private:
   UDPSocket(NativeSocket socket);
 
Index: lldb/include/lldb/Host/common/TCPSocket.h
===================================================================
--- lldb/include/lldb/Host/common/TCPSocket.h
+++ lldb/include/lldb/Host/common/TCPSocket.h
@@ -46,6 +46,8 @@
 
   bool IsValid() const override;
 
+  std::string GetConnectURI() const override;
+
 private:
   TCPSocket(NativeSocket socket, const TCPSocket &listen_socket);
 
Index: lldb/include/lldb/Host/Socket.h
===================================================================
--- lldb/include/lldb/Host/Socket.h
+++ lldb/include/lldb/Host/Socket.h
@@ -102,6 +102,9 @@
                                 std::string &host_str, std::string &port_str,
                                 int32_t &port, Status *error_ptr);
 
+  // If this Socket is connected then return the URI used to connect.
+  virtual std::string GetConnectURI() const { return ""; };
+
 protected:
   Socket(SocketProtocol protocol, bool should_close,
          bool m_child_process_inherit);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to