forked from OSchip/llvm-project
Make ConnectionFileDescription work with all sockets
Summary: 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. Reviewers: labath, clayborg, xiaobai Reviewed By: labath Subscribers: mgorny, jfb, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D62089 llvm-svn: 362173
This commit is contained in:
parent
375dec5e45
commit
d556095135
|
@ -102,6 +102,9 @@ public:
|
|||
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 GetRemoteConnectionURI() const { return ""; };
|
||||
|
||||
protected:
|
||||
Socket(SocketProtocol protocol, bool should_close,
|
||||
bool m_child_process_inherit);
|
||||
|
|
|
@ -46,6 +46,8 @@ public:
|
|||
|
||||
bool IsValid() const override;
|
||||
|
||||
std::string GetRemoteConnectionURI() const override;
|
||||
|
||||
private:
|
||||
TCPSocket(NativeSocket socket, const TCPSocket &listen_socket);
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ public:
|
|||
static Status Connect(llvm::StringRef name, bool child_processes_inherit,
|
||||
Socket *&socket);
|
||||
|
||||
std::string GetRemoteConnectionURI() const override;
|
||||
|
||||
private:
|
||||
UDPSocket(NativeSocket socket);
|
||||
|
||||
|
|
|
@ -20,11 +20,14 @@ public:
|
|||
Status Listen(llvm::StringRef name, int backlog) override;
|
||||
Status Accept(Socket *&socket) override;
|
||||
|
||||
std::string GetRemoteConnectionURI() 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);
|
||||
|
|
|
@ -118,6 +118,14 @@ std::string TCPSocket::GetRemoteIPAddress() const {
|
|||
return "";
|
||||
}
|
||||
|
||||
std::string TCPSocket::GetRemoteConnectionURI() const {
|
||||
if (m_socket != kInvalidSocketValue) {
|
||||
return llvm::formatv("connect://[{0}]:{1}", GetRemoteIPAddress(),
|
||||
GetRemotePortNumber());
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
Status TCPSocket::CreateSocket(int domain) {
|
||||
Status error;
|
||||
if (IsValid())
|
||||
|
|
|
@ -134,3 +134,11 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
|
|||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
|
||||
std::string UDPSocket::GetRemoteConnectionURI() const {
|
||||
if (m_socket != kInvalidSocketValue) {
|
||||
return llvm::formatv("udp://[{0}]:{1}", m_sockaddr.GetIPAddress(),
|
||||
m_sockaddr.GetPort());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -758,13 +758,7 @@ void ConnectionFileDescriptor::SetChildProcessesInherit(
|
|||
}
|
||||
|
||||
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->GetRemoteConnectionURI();
|
||||
}
|
||||
|
|
|
@ -125,3 +125,28 @@ size_t DomainSocket::GetNameOffset() const { return 0; }
|
|||
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::GetRemoteConnectionURI() const {
|
||||
if (m_socket != kInvalidSocketValue) {
|
||||
return llvm::formatv("{0}://{1}",
|
||||
GetNameOffset() == 0 ? "unix-connect"
|
||||
: "unix-abstract-connect",
|
||||
GetSocketName());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -115,25 +115,24 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
|
|||
this, std::placeholders::_1),
|
||||
false);
|
||||
|
||||
llvm::StringRef platform_scheme;
|
||||
llvm::StringRef platform_ip;
|
||||
int platform_port;
|
||||
llvm::StringRef platform_path;
|
||||
std::string platform_uri = GetConnection()->GetURI();
|
||||
bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip,
|
||||
platform_port, platform_path);
|
||||
UNUSED_IF_ASSERT_DISABLED(ok);
|
||||
assert(ok);
|
||||
|
||||
std::ostringstream url;
|
||||
// debugserver does not accept the URL scheme prefix.
|
||||
#if !defined(__APPLE__)
|
||||
url << m_socket_scheme << "://";
|
||||
#endif
|
||||
uint16_t *port_ptr = &port;
|
||||
if (m_socket_protocol == Socket::ProtocolTcp)
|
||||
if (m_socket_protocol == Socket::ProtocolTcp) {
|
||||
llvm::StringRef platform_scheme;
|
||||
llvm::StringRef platform_ip;
|
||||
int platform_port;
|
||||
llvm::StringRef platform_path;
|
||||
std::string platform_uri = GetConnection()->GetURI();
|
||||
bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip,
|
||||
platform_port, platform_path);
|
||||
UNUSED_IF_ASSERT_DISABLED(ok);
|
||||
assert(ok);
|
||||
url << platform_ip.str() << ":" << port;
|
||||
else {
|
||||
} else {
|
||||
socket_name = GetDomainSocketPath("gdbserver").GetPath();
|
||||
url << socket_name;
|
||||
port_ptr = nullptr;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SocketTestUtilities.h"
|
||||
#include "lldb/Utility/UriParser.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace lldb_private;
|
||||
|
@ -147,3 +148,64 @@ TEST_F(SocketTest, TCPListen0GetPort) {
|
|||
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;
|
||||
std::string uri(socket_a_up->GetRemoteConnectionURI());
|
||||
EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path));
|
||||
EXPECT_EQ(scheme, "connect");
|
||||
EXPECT_EQ(port, socket_a_up->GetRemotePortNumber());
|
||||
}
|
||||
|
||||
TEST_F(SocketTest, UDPGetConnectURI) {
|
||||
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;
|
||||
std::string uri(socket->GetRemoteConnectionURI());
|
||||
EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path));
|
||||
EXPECT_EQ(scheme, "udp");
|
||||
}
|
||||
|
||||
#ifndef LLDB_DISABLE_POSIX
|
||||
TEST_F(SocketTest, DomainGetConnectURI) {
|
||||
llvm::SmallString<64> domain_path;
|
||||
std::error_code EC =
|
||||
llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", domain_path);
|
||||
ASSERT_FALSE(EC);
|
||||
llvm::sys::path::append(domain_path, "test");
|
||||
|
||||
std::unique_ptr<DomainSocket> socket_a_up;
|
||||
std::unique_ptr<DomainSocket> socket_b_up;
|
||||
CreateDomainConnectedSockets(domain_path, &socket_a_up, &socket_b_up);
|
||||
|
||||
llvm::StringRef scheme;
|
||||
llvm::StringRef hostname;
|
||||
int port;
|
||||
llvm::StringRef path;
|
||||
std::string uri(socket_a_up->GetRemoteConnectionURI());
|
||||
EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path));
|
||||
EXPECT_EQ(scheme, "unix-connect");
|
||||
EXPECT_EQ(path, domain_path);
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue