forked from OSchip/llvm-project
Modified local spawning in debugserver processes to use a new --reverse-connect option so that debugserver actually connects back to LLDB instead of LLDB connecting to debugserver.
This gets rid of our hacky "get_random_port()" which would grab a random port and tell debugserver to open that port. Now LLDB creates, binds, listens and accepts a connection by binding to port zero and sending the correctly bound port down as the host:port to connect back to. Fixed the "ConnectionFileDescriptor" to be able to correctly listen for connections from a specified host, localhost, or any host. Prior to this fix "listen://" only accepted the following format: listen://<port> But now it can accept: listen://<port> // Listen for connection from localhost on port <port> listen://<host>:<port> // Listen for connection from <host> and <port> listen://*:<port> // Listen for connection from any host on port <port> llvm-svn: 196547
This commit is contained in:
parent
58683755ed
commit
00fe87b488
|
@ -76,6 +76,9 @@ public:
|
||||||
in_port_t
|
in_port_t
|
||||||
GetWritePort () const;
|
GetWritePort () const;
|
||||||
|
|
||||||
|
in_port_t
|
||||||
|
GetBoundPort (uint32_t timeout_sec);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -95,7 +98,7 @@ protected:
|
||||||
BytesAvailable (uint32_t timeout_usec, Error *error_ptr);
|
BytesAvailable (uint32_t timeout_usec, Error *error_ptr);
|
||||||
|
|
||||||
lldb::ConnectionStatus
|
lldb::ConnectionStatus
|
||||||
SocketListen (uint16_t listen_port_num, Error *error_ptr);
|
SocketListen (const char *host_and_port, Error *error_ptr);
|
||||||
|
|
||||||
lldb::ConnectionStatus
|
lldb::ConnectionStatus
|
||||||
ConnectTCP (const char *host_and_port, Error *error_ptr);
|
ConnectTCP (const char *host_and_port, Error *error_ptr);
|
||||||
|
@ -117,11 +120,12 @@ protected:
|
||||||
FDType m_fd_send_type;
|
FDType m_fd_send_type;
|
||||||
FDType m_fd_recv_type;
|
FDType m_fd_recv_type;
|
||||||
std::unique_ptr<SocketAddress> m_udp_send_sockaddr;
|
std::unique_ptr<SocketAddress> m_udp_send_sockaddr;
|
||||||
bool m_should_close_fd; // True if this class should close the file descriptor when it goes away.
|
|
||||||
uint32_t m_socket_timeout_usec;
|
uint32_t m_socket_timeout_usec;
|
||||||
int m_pipe_read; // A pipe that we select on the reading end of along with
|
int m_pipe_read; // A pipe that we select on the reading end of along with
|
||||||
int m_pipe_write; // m_fd_recv so we can force ourselves out of the select.
|
int m_pipe_write; // m_fd_recv so we can force ourselves out of the select.
|
||||||
Mutex m_mutex;
|
Mutex m_mutex;
|
||||||
|
Predicate<in_port_t> m_port_predicate; // Used when binding to port zero to wait for the thread that creates the socket, binds and listens to resolve the port number
|
||||||
|
bool m_should_close_fd; // True if this class should close the file descriptor when it goes away.
|
||||||
bool m_shutting_down; // This marks that we are shutting down so if we get woken up from BytesAvailable
|
bool m_shutting_down; // This marks that we are shutting down so if we get woken up from BytesAvailable
|
||||||
// to disconnect, we won't try to read again.
|
// to disconnect, we won't try to read again.
|
||||||
|
|
||||||
|
|
|
@ -121,10 +121,12 @@ public:
|
||||||
// address.
|
// address.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SetAddress (const struct addrinfo *hints_ptr, // Optional hints where the family, protocol and other things can be specified.
|
getaddrinfo (const char *host, // Hostname ("foo.bar.com" or "foo" or IP address string ("123.234.12.1" or "2001:0db8:85a3:0000:0000:8a2e:0370:7334")
|
||||||
const char *host, // Hostname ("foo.bar.com" or "foo" or IP address string ("123.234.12.1" or "2001:0db8:85a3:0000:0000:8a2e:0370:7334")
|
|
||||||
const char *service, // Protocol name ("tcp", "http", etc) or a raw port number string ("81")
|
const char *service, // Protocol name ("tcp", "http", etc) or a raw port number string ("81")
|
||||||
struct addrinfo *addr_info_ptr); // If non-NULL, this will get filled in with the match
|
int ai_family = PF_UNSPEC,
|
||||||
|
int ai_socktype = 0,
|
||||||
|
int ai_protocol = 0,
|
||||||
|
int ai_flags = 0);
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// Quick way to set the SocketAddress to localhost given the family.
|
// Quick way to set the SocketAddress to localhost given the family.
|
||||||
|
@ -135,6 +137,10 @@ public:
|
||||||
SetToLocalhost (sa_family_t family,
|
SetToLocalhost (sa_family_t family,
|
||||||
in_port_t port);
|
in_port_t port);
|
||||||
|
|
||||||
|
bool
|
||||||
|
SetToAnyAddress (sa_family_t family,
|
||||||
|
in_port_t port);
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// Returns true if there is a valid socket address in this object.
|
// Returns true if there is a valid socket address in this object.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -97,11 +97,11 @@ ConnectionFileDescriptor::ConnectionFileDescriptor () :
|
||||||
m_fd_send_type (eFDTypeFile),
|
m_fd_send_type (eFDTypeFile),
|
||||||
m_fd_recv_type (eFDTypeFile),
|
m_fd_recv_type (eFDTypeFile),
|
||||||
m_udp_send_sockaddr (new SocketAddress()),
|
m_udp_send_sockaddr (new SocketAddress()),
|
||||||
m_should_close_fd (false),
|
|
||||||
m_socket_timeout_usec(0),
|
m_socket_timeout_usec(0),
|
||||||
m_pipe_read(-1),
|
m_pipe_read(-1),
|
||||||
m_pipe_write(-1),
|
m_pipe_write(-1),
|
||||||
m_mutex (Mutex::eMutexTypeRecursive),
|
m_mutex (Mutex::eMutexTypeRecursive),
|
||||||
|
m_should_close_fd (false),
|
||||||
m_shutting_down (false)
|
m_shutting_down (false)
|
||||||
{
|
{
|
||||||
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
|
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
|
||||||
|
@ -116,11 +116,11 @@ ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) :
|
||||||
m_fd_send_type (eFDTypeFile),
|
m_fd_send_type (eFDTypeFile),
|
||||||
m_fd_recv_type (eFDTypeFile),
|
m_fd_recv_type (eFDTypeFile),
|
||||||
m_udp_send_sockaddr (new SocketAddress()),
|
m_udp_send_sockaddr (new SocketAddress()),
|
||||||
m_should_close_fd (owns_fd),
|
|
||||||
m_socket_timeout_usec(0),
|
m_socket_timeout_usec(0),
|
||||||
m_pipe_read(-1),
|
m_pipe_read(-1),
|
||||||
m_pipe_write(-1),
|
m_pipe_write(-1),
|
||||||
m_mutex (Mutex::eMutexTypeRecursive),
|
m_mutex (Mutex::eMutexTypeRecursive),
|
||||||
|
m_should_close_fd (owns_fd),
|
||||||
m_shutting_down (false)
|
m_shutting_down (false)
|
||||||
{
|
{
|
||||||
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
|
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
|
||||||
|
@ -218,12 +218,15 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
|
||||||
|
|
||||||
if (s && s[0])
|
if (s && s[0])
|
||||||
{
|
{
|
||||||
char *end = NULL;
|
|
||||||
if (strstr(s, "listen://"))
|
if (strstr(s, "listen://"))
|
||||||
{
|
{
|
||||||
// listen://HOST:PORT
|
// listen://HOST:PORT
|
||||||
unsigned long listen_port = ::strtoul(s + strlen("listen://"), &end, 0);
|
return SocketListen (s + strlen("listen://"), error_ptr);
|
||||||
return SocketListen (listen_port, error_ptr);
|
}
|
||||||
|
else if (strstr(s, "accept://"))
|
||||||
|
{
|
||||||
|
// unix://SOCKNAME
|
||||||
|
return NamedSocketAccept (s + strlen("accept://"), error_ptr);
|
||||||
}
|
}
|
||||||
else if (strstr(s, "unix-accept://"))
|
else if (strstr(s, "unix-accept://"))
|
||||||
{
|
{
|
||||||
|
@ -363,6 +366,9 @@ ConnectionFileDescriptor::Disconnect (Error *error_ptr)
|
||||||
if (log)
|
if (log)
|
||||||
log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this);
|
log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this);
|
||||||
|
|
||||||
|
// Reset the port predicate when disconnecting and don't broadcast
|
||||||
|
m_port_predicate.SetValue(0, eBroadcastNever);
|
||||||
|
|
||||||
ConnectionStatus status = eConnectionStatusSuccess;
|
ConnectionStatus status = eConnectionStatusSuccess;
|
||||||
|
|
||||||
if (m_fd_send < 0 && m_fd_recv < 0)
|
if (m_fd_send < 0 && m_fd_recv < 0)
|
||||||
|
@ -1281,16 +1287,31 @@ ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *er
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionStatus
|
ConnectionStatus
|
||||||
ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_ptr)
|
ConnectionFileDescriptor::SocketListen (const char *host_and_port, Error *error_ptr)
|
||||||
{
|
{
|
||||||
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
|
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
|
||||||
if (log)
|
if (log)
|
||||||
log->Printf ("%p ConnectionFileDescriptor::SocketListen (port = %i)", this, listen_port_num);
|
log->Printf ("%p ConnectionFileDescriptor::SocketListen (%s)", this, host_and_port);
|
||||||
|
|
||||||
Disconnect (NULL);
|
Disconnect (NULL);
|
||||||
m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
|
m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
|
||||||
int listen_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
std::string host_str;
|
||||||
if (listen_port == -1)
|
std::string port_str;
|
||||||
|
int32_t port = INT32_MIN;
|
||||||
|
if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
|
||||||
|
{
|
||||||
|
// Might be just a port number
|
||||||
|
port = Args::StringToSInt32(host_and_port, -1);
|
||||||
|
if (port == -1)
|
||||||
|
return eConnectionStatusError;
|
||||||
|
else
|
||||||
|
host_str.clear();
|
||||||
|
}
|
||||||
|
const sa_family_t family = AF_INET;
|
||||||
|
const int socktype = SOCK_STREAM;
|
||||||
|
const int protocol = IPPROTO_TCP;
|
||||||
|
int listen_fd = ::socket (family, socktype, protocol);
|
||||||
|
if (listen_fd == -1)
|
||||||
{
|
{
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
error_ptr->SetErrorToErrno();
|
error_ptr->SetErrorToErrno();
|
||||||
|
@ -1298,41 +1319,114 @@ ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_p
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable local address reuse
|
// enable local address reuse
|
||||||
SetSocketOption (listen_port, SOL_SOCKET, SO_REUSEADDR, 1);
|
SetSocketOption (listen_fd, SOL_SOCKET, SO_REUSEADDR, 1);
|
||||||
|
|
||||||
SocketAddress localhost;
|
SocketAddress listen_addr;
|
||||||
if (localhost.SetToLocalhost (AF_INET, listen_port_num))
|
if (host_str.empty())
|
||||||
|
listen_addr.SetToLocalhost(family, port);
|
||||||
|
else if (host_str.compare("*") == 0)
|
||||||
|
listen_addr.SetToAnyAddress(family, port);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
int err = ::bind (listen_port, localhost, localhost.GetLength());
|
if (!listen_addr.getaddrinfo(host_str.c_str(), port_str.c_str(), family, socktype, protocol))
|
||||||
|
{
|
||||||
|
if (error_ptr)
|
||||||
|
error_ptr->SetErrorStringWithFormat("unable to resolve hostname '%s'", host_str.c_str());
|
||||||
|
Close (listen_fd, eFDTypeSocket, NULL);
|
||||||
|
return eConnectionStatusError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SocketAddress anyaddr;
|
||||||
|
if (anyaddr.SetToAnyAddress (family, port))
|
||||||
|
{
|
||||||
|
int err = ::bind (listen_fd, anyaddr, anyaddr.GetLength());
|
||||||
if (err == -1)
|
if (err == -1)
|
||||||
{
|
{
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
error_ptr->SetErrorToErrno();
|
error_ptr->SetErrorToErrno();
|
||||||
Close (listen_port, eFDTypeSocket, NULL);
|
Close (listen_fd, eFDTypeSocket, NULL);
|
||||||
return eConnectionStatusError;
|
return eConnectionStatusError;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ::listen (listen_port, 1);
|
err = ::listen (listen_fd, 1);
|
||||||
if (err == -1)
|
if (err == -1)
|
||||||
{
|
{
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
error_ptr->SetErrorToErrno();
|
error_ptr->SetErrorToErrno();
|
||||||
Close (listen_port, eFDTypeSocket, NULL);
|
Close (listen_fd, eFDTypeSocket, NULL);
|
||||||
return eConnectionStatusError;
|
return eConnectionStatusError;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fd_send = m_fd_recv = ::accept (listen_port, NULL, 0);
|
// We were asked to listen on port zero which means we
|
||||||
|
// must now read the actual port that was given to us
|
||||||
|
// as port zero is a special code for "find an open port
|
||||||
|
// for me".
|
||||||
|
if (port == 0)
|
||||||
|
port = GetSocketPort(listen_fd);
|
||||||
|
|
||||||
|
// Set the port predicate since when doing a listen://<host>:<port>
|
||||||
|
// it often needs to accept the incoming connection which is a blocking
|
||||||
|
// system call. Allowing access to the bound port using a predicate allows
|
||||||
|
// us to wait for the port predicate to be set to a non-zero value from
|
||||||
|
// another thread in an efficient manor.
|
||||||
|
m_port_predicate.SetValue(port, eBroadcastAlways);
|
||||||
|
|
||||||
|
|
||||||
|
bool accept_connection = false;
|
||||||
|
|
||||||
|
// Loop until we are happy with our connection
|
||||||
|
while (!accept_connection)
|
||||||
|
{
|
||||||
|
struct sockaddr_in accept_addr;
|
||||||
|
::memset (&accept_addr, 0, sizeof accept_addr);
|
||||||
|
accept_addr.sin_len = sizeof accept_addr;
|
||||||
|
socklen_t accept_addr_len = sizeof accept_addr;
|
||||||
|
|
||||||
|
int fd = ::accept (listen_fd, (struct sockaddr *)&accept_addr, &accept_addr_len);
|
||||||
|
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
if (error_ptr)
|
||||||
|
error_ptr->SetErrorToErrno();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen_addr.sockaddr_in().sin_addr.s_addr == INADDR_ANY)
|
||||||
|
{
|
||||||
|
accept_connection = true;
|
||||||
|
m_fd_send = m_fd_recv = fd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (accept_addr_len == listen_addr.sockaddr_in().sin_len &&
|
||||||
|
accept_addr.sin_addr.s_addr == listen_addr.sockaddr_in().sin_addr.s_addr)
|
||||||
|
{
|
||||||
|
accept_connection = true;
|
||||||
|
m_fd_send = m_fd_recv = fd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::close (fd);
|
||||||
|
m_fd_send = m_fd_recv = -1;
|
||||||
|
const uint8_t *accept_ip = (const uint8_t *)&accept_addr.sin_addr.s_addr;
|
||||||
|
const uint8_t *listen_ip = (const uint8_t *)&listen_addr.sockaddr_in().sin_addr.s_addr;
|
||||||
|
::fprintf (stderr, "error: rejecting incoming connection from %u.%u.%u.%u (expecting %u.%u.%u.%u)\n",
|
||||||
|
accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
|
||||||
|
listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_fd_send == -1)
|
if (m_fd_send == -1)
|
||||||
{
|
{
|
||||||
if (error_ptr)
|
Close (listen_fd, eFDTypeSocket, NULL);
|
||||||
error_ptr->SetErrorToErrno();
|
|
||||||
Close (listen_port, eFDTypeSocket, NULL);
|
|
||||||
return eConnectionStatusError;
|
return eConnectionStatusError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are done with the listen port
|
// We are done with the listen port
|
||||||
Close (listen_port, eFDTypeSocket, NULL);
|
Close (listen_fd, eFDTypeSocket, NULL);
|
||||||
|
|
||||||
m_should_close_fd = true;
|
m_should_close_fd = true;
|
||||||
|
|
||||||
|
@ -1446,7 +1540,7 @@ ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_pt
|
||||||
{
|
{
|
||||||
// Socket was created, now lets bind to the requested port
|
// Socket was created, now lets bind to the requested port
|
||||||
SocketAddress addr;
|
SocketAddress addr;
|
||||||
addr.SetToLocalhost (AF_INET, 0);
|
addr.SetToAnyAddress (AF_INET, 0);
|
||||||
|
|
||||||
if (::bind (m_fd_recv, addr, addr.GetLength()) == -1)
|
if (::bind (m_fd_recv, addr, addr.GetLength()) == -1)
|
||||||
{
|
{
|
||||||
|
@ -1585,11 +1679,13 @@ in_port_t
|
||||||
ConnectionFileDescriptor::GetSocketPort (int fd)
|
ConnectionFileDescriptor::GetSocketPort (int fd)
|
||||||
{
|
{
|
||||||
// We bound to port zero, so we need to figure out which port we actually bound to
|
// We bound to port zero, so we need to figure out which port we actually bound to
|
||||||
|
if (fd >= 0)
|
||||||
|
{
|
||||||
SocketAddress sock_addr;
|
SocketAddress sock_addr;
|
||||||
socklen_t sock_addr_len = sock_addr.GetMaxLength ();
|
socklen_t sock_addr_len = sock_addr.GetMaxLength ();
|
||||||
if (::getsockname (fd, sock_addr, &sock_addr_len) == 0)
|
if (::getsockname (fd, sock_addr, &sock_addr_len) == 0)
|
||||||
return sock_addr.GetPort ();
|
return sock_addr.GetPort ();
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1609,4 +1705,17 @@ ConnectionFileDescriptor::GetWritePort () const
|
||||||
return ConnectionFileDescriptor::GetSocketPort (m_fd_send);
|
return ConnectionFileDescriptor::GetSocketPort (m_fd_send);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in_port_t
|
||||||
|
ConnectionFileDescriptor::GetBoundPort (uint32_t timeout_sec)
|
||||||
|
{
|
||||||
|
in_port_t bound_port = 0;
|
||||||
|
if (timeout_sec == UINT32_MAX)
|
||||||
|
m_port_predicate.WaitForValueNotEqualTo (0, bound_port);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TimeValue timeout = TimeValue::Now();
|
||||||
|
timeout.OffsetWithSeconds(timeout_sec);
|
||||||
|
m_port_predicate.WaitForValueNotEqualTo (0, bound_port, &timeout);
|
||||||
|
}
|
||||||
|
return bound_port;
|
||||||
|
}
|
||||||
|
|
|
@ -128,8 +128,8 @@ SocketAddress::GetPort () const
|
||||||
{
|
{
|
||||||
switch (GetFamily())
|
switch (GetFamily())
|
||||||
{
|
{
|
||||||
case AF_INET: return m_socket_addr.sa_ipv4.sin_port;
|
case AF_INET: return ntohs(m_socket_addr.sa_ipv4.sin_port);
|
||||||
case AF_INET6: return m_socket_addr.sa_ipv6.sin6_port;
|
case AF_INET6: return ntohs(m_socket_addr.sa_ipv6.sin6_port);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -206,36 +206,62 @@ SocketAddress::operator=(const struct sockaddr_storage &s)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SocketAddress::SetAddress (const struct addrinfo *hints_ptr,
|
SocketAddress::getaddrinfo (const char *host,
|
||||||
const char *host,
|
|
||||||
const char *service,
|
const char *service,
|
||||||
struct addrinfo *addr_info_ptr)
|
int ai_family,
|
||||||
|
int ai_socktype,
|
||||||
|
int ai_protocol,
|
||||||
|
int ai_flags)
|
||||||
{
|
{
|
||||||
|
struct addrinfo hints;
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = ai_family;
|
||||||
|
hints.ai_socktype = ai_socktype;
|
||||||
|
hints.ai_protocol = ai_protocol;
|
||||||
|
hints.ai_flags = ai_flags;
|
||||||
|
|
||||||
struct addrinfo *service_info_list = NULL;
|
struct addrinfo *service_info_list = NULL;
|
||||||
int err = ::getaddrinfo (host, service, hints_ptr, &service_info_list);
|
int err = ::getaddrinfo (host, service, &hints, &service_info_list);
|
||||||
if (err == 0 && service_info_list)
|
if (err == 0 && service_info_list)
|
||||||
{
|
|
||||||
if (addr_info_ptr)
|
|
||||||
*addr_info_ptr = *service_info_list;
|
|
||||||
*this = service_info_list;
|
*this = service_info_list;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
:: freeaddrinfo (service_info_list);
|
:: freeaddrinfo (service_info_list);
|
||||||
|
return IsValid();
|
||||||
const bool is_valid = IsValid();
|
|
||||||
if (!is_valid)
|
|
||||||
{
|
|
||||||
if (addr_info_ptr)
|
|
||||||
::memset (addr_info_ptr, 0, sizeof(struct addrinfo));
|
|
||||||
}
|
|
||||||
return is_valid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SocketAddress::SetToLocalhost (sa_family_t family, in_port_t port)
|
SocketAddress::SetToLocalhost (sa_family_t family, in_port_t port)
|
||||||
|
{
|
||||||
|
switch (family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
SetFamily (AF_INET);
|
||||||
|
if (SetPort (port))
|
||||||
|
{
|
||||||
|
m_socket_addr.sa_ipv4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
SetFamily (AF_INET6);
|
||||||
|
if (SetPort (port))
|
||||||
|
{
|
||||||
|
m_socket_addr.sa_ipv6.sin6_addr = in6addr_loopback;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
Clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SocketAddress::SetToAnyAddress (sa_family_t family, in_port_t port)
|
||||||
{
|
{
|
||||||
switch (family)
|
switch (family)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
// C++ Includes
|
// C++ Includes
|
||||||
// Other libraries and framework includes
|
// Other libraries and framework includes
|
||||||
|
#include "lldb/Core/ConnectionFileDescriptor.h"
|
||||||
#include "lldb/Core/Log.h"
|
#include "lldb/Core/Log.h"
|
||||||
#include "lldb/Core/StreamFile.h"
|
#include "lldb/Core/StreamFile.h"
|
||||||
#include "lldb/Core/StreamString.h"
|
#include "lldb/Core/StreamString.h"
|
||||||
|
@ -144,7 +145,9 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
|
||||||
m_private_is_running (false),
|
m_private_is_running (false),
|
||||||
m_history (512),
|
m_history (512),
|
||||||
m_send_acks (true),
|
m_send_acks (true),
|
||||||
m_is_platform (is_platform)
|
m_is_platform (is_platform),
|
||||||
|
m_listen_thread (LLDB_INVALID_HOST_THREAD),
|
||||||
|
m_listen_url ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +542,56 @@ GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, Stri
|
||||||
}
|
}
|
||||||
|
|
||||||
Error
|
Error
|
||||||
GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
|
GDBRemoteCommunication::StartListenThread (const char *hostname, in_port_t port)
|
||||||
|
{
|
||||||
|
Error error;
|
||||||
|
if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread))
|
||||||
|
{
|
||||||
|
error.SetErrorString("listen thread already running");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char listen_url[512];
|
||||||
|
if (hostname && hostname[0])
|
||||||
|
snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname ? hostname : "localhost", port);
|
||||||
|
else
|
||||||
|
snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
|
||||||
|
m_listen_url = listen_url;
|
||||||
|
SetConnection(new ConnectionFileDescriptor());
|
||||||
|
m_listen_thread = Host::ThreadCreate (listen_url, GDBRemoteCommunication::ListenThread, this, &error);
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GDBRemoteCommunication::JoinListenThread ()
|
||||||
|
{
|
||||||
|
if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread))
|
||||||
|
{
|
||||||
|
Host::ThreadJoin(m_listen_thread, NULL, NULL);
|
||||||
|
m_listen_thread = LLDB_INVALID_HOST_THREAD;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::thread_result_t
|
||||||
|
GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
|
||||||
|
{
|
||||||
|
GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
|
||||||
|
Error error;
|
||||||
|
ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)comm->GetConnection ();
|
||||||
|
|
||||||
|
if (connection)
|
||||||
|
{
|
||||||
|
// Do the listen on another thread so we can continue on...
|
||||||
|
if (connection->Connect(comm->m_listen_url.c_str(), &error) != eConnectionStatusSuccess)
|
||||||
|
comm->SetConnection(NULL);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error
|
||||||
|
GDBRemoteCommunication::StartDebugserverProcess (const char *host_and_port,
|
||||||
lldb_private::ProcessLaunchInfo &launch_info,
|
lldb_private::ProcessLaunchInfo &launch_info,
|
||||||
uint16_t &port)
|
uint16_t &port)
|
||||||
{
|
{
|
||||||
|
@ -594,7 +646,10 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
|
||||||
|
|
||||||
// Start args with "debugserver /file/path -r --"
|
// Start args with "debugserver /file/path -r --"
|
||||||
debugserver_args.AppendArgument(debugserver_path);
|
debugserver_args.AppendArgument(debugserver_path);
|
||||||
debugserver_args.AppendArgument(debugserver_url);
|
|
||||||
|
// If a host and port is supplied then use it
|
||||||
|
if (host_and_port)
|
||||||
|
debugserver_args.AppendArgument(host_and_port);
|
||||||
// use native registers, not the GDB registers
|
// use native registers, not the GDB registers
|
||||||
debugserver_args.AppendArgument("--native-regs");
|
debugserver_args.AppendArgument("--native-regs");
|
||||||
// make debugserver run in its own session so signals generated by
|
// make debugserver run in its own session so signals generated by
|
||||||
|
@ -603,6 +658,8 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
|
||||||
|
|
||||||
char named_pipe_path[PATH_MAX];
|
char named_pipe_path[PATH_MAX];
|
||||||
|
|
||||||
|
if (host_and_port)
|
||||||
|
{
|
||||||
// Create a temporary file to get the stdout/stderr and redirect the
|
// Create a temporary file to get the stdout/stderr and redirect the
|
||||||
// output of the command into this file. We will later read this file
|
// output of the command into this file. We will later read this file
|
||||||
// if all goes well and fill the data into "command_output_ptr"
|
// if all goes well and fill the data into "command_output_ptr"
|
||||||
|
@ -629,6 +686,28 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
named_pipe_path[0] = '\0';
|
named_pipe_path[0] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
named_pipe_path[0] = '\0';
|
||||||
|
|
||||||
|
// No host and port given, so lets listen on our end and make the debugserver
|
||||||
|
// connect to us..
|
||||||
|
error = StartListenThread ("localhost", 0);
|
||||||
|
if (error.Fail())
|
||||||
|
return error;
|
||||||
|
|
||||||
|
ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
|
||||||
|
port = connection->GetBoundPort(3);
|
||||||
|
assert (port != 0);
|
||||||
|
char port_cstr[32];
|
||||||
|
snprintf(port_cstr, sizeof(port_cstr), "localhost:%i", port);
|
||||||
|
// Send the host and port down that debugserver and specify an option
|
||||||
|
// so that it connects back to the port we are listening to in this process
|
||||||
|
debugserver_args.AppendArgument("--reverse-connect");
|
||||||
|
debugserver_args.AppendArgument(port_cstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
|
const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
|
||||||
if (env_debugserver_log_file)
|
if (env_debugserver_log_file)
|
||||||
|
@ -669,7 +748,11 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
|
||||||
}
|
}
|
||||||
Host::Unlink(named_pipe_path);
|
Host::Unlink(named_pipe_path);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Make sure we actually connect with the debugserver...
|
||||||
|
JoinListenThread();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -108,8 +108,8 @@ public:
|
||||||
// Start a debugserver instance on the current host using the
|
// Start a debugserver instance on the current host using the
|
||||||
// supplied connection URL.
|
// supplied connection URL.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
static lldb_private::Error
|
lldb_private::Error
|
||||||
StartDebugserverProcess (const char *connect_url,
|
StartDebugserverProcess (const char *host_and_port,
|
||||||
lldb_private::ProcessLaunchInfo &launch_info,
|
lldb_private::ProcessLaunchInfo &launch_info,
|
||||||
uint16_t &port);
|
uint16_t &port);
|
||||||
|
|
||||||
|
@ -256,9 +256,22 @@ protected:
|
||||||
// a single process
|
// a single process
|
||||||
|
|
||||||
|
|
||||||
|
lldb_private::Error
|
||||||
|
StartListenThread (const char *hostname = "localhost",
|
||||||
|
in_port_t port = 0);
|
||||||
|
|
||||||
|
bool
|
||||||
|
JoinListenThread ();
|
||||||
|
|
||||||
|
static lldb::thread_result_t
|
||||||
|
ListenThread (lldb::thread_arg_t arg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
lldb::thread_t m_listen_thread;
|
||||||
|
std::string m_listen_url;
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// For GDBRemoteCommunication only
|
// For GDBRemoteCommunication only
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
|
@ -812,7 +812,7 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
|
||||||
|
|
||||||
debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
|
debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
|
||||||
|
|
||||||
error = GDBRemoteCommunication::StartDebugserverProcess (host_and_port_cstr,
|
error = StartDebugserverProcess (host_and_port_cstr,
|
||||||
debugserver_launch_info,
|
debugserver_launch_info,
|
||||||
port);
|
port);
|
||||||
|
|
||||||
|
@ -1130,7 +1130,6 @@ GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packe
|
||||||
mode_t mode = packet.GetHexMaxU32(false, 0600);
|
mode_t mode = packet.GetHexMaxU32(false, 0600);
|
||||||
Error error;
|
Error error;
|
||||||
int fd = ::open (path.c_str(), flags, mode);
|
int fd = ::open (path.c_str(), flags, mode);
|
||||||
printf ("open('%s', flags=0x%x, mode=%o) fd = %i (%s)\n", path.c_str(), flags, mode, fd, fd == -1 ? strerror(errno) : "<success>");
|
|
||||||
const int save_errno = fd == -1 ? errno : 0;
|
const int save_errno = fd == -1 ? errno : 0;
|
||||||
StreamString response;
|
StreamString response;
|
||||||
response.PutChar('F');
|
response.PutChar('F');
|
||||||
|
|
|
@ -845,7 +845,10 @@ Error
|
||||||
ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
|
ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
// Sleep and wait a bit for debugserver to start to listen...
|
// Only connect if we have a valid connect URL
|
||||||
|
|
||||||
|
if (connect_url && connect_url[0])
|
||||||
|
{
|
||||||
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
|
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
|
||||||
if (conn_ap.get())
|
if (conn_ap.get())
|
||||||
{
|
{
|
||||||
|
@ -872,6 +875,7 @@ ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
|
||||||
usleep (100000);
|
usleep (100000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_gdb_comm.IsConnected())
|
if (!m_gdb_comm.IsConnected())
|
||||||
{
|
{
|
||||||
|
@ -2501,7 +2505,7 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
|
||||||
debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
|
debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
|
||||||
debugserver_launch_info.SetUserID(process_info.GetUserID());
|
debugserver_launch_info.SetUserID(process_info.GetUserID());
|
||||||
|
|
||||||
error = GDBRemoteCommunication::StartDebugserverProcess ("localhost:0",
|
error = m_gdb_comm.StartDebugserverProcess (NULL,
|
||||||
debugserver_launch_info,
|
debugserver_launch_info,
|
||||||
port);
|
port);
|
||||||
|
|
||||||
|
@ -2522,10 +2526,17 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_gdb_comm.IsConnected())
|
||||||
|
{
|
||||||
|
// Finish the connection process by doing the handshake without connecting (send NULL URL)
|
||||||
|
ConnectToDebugserver (NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
char connect_url[128];
|
char connect_url[128];
|
||||||
snprintf (connect_url, sizeof(connect_url), "connect://localhost:%u", port);
|
snprintf (connect_url, sizeof(connect_url), "connect://localhost:%u", port);
|
||||||
|
|
||||||
error = ConnectToDebugserver (connect_url);
|
error = ConnectToDebugserver (connect_url);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -644,21 +644,34 @@ PortWasBoundCallbackNamedPipe (const void *baton, in_port_t port)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
StartListening (RNBRemote *remote, const char *listen_host, int listen_port, const char *named_pipe_path)
|
ConnectRemote (RNBRemote *remote, const char *host, int port, bool reverse_connect, const char *named_pipe_path)
|
||||||
{
|
{
|
||||||
if (!remote->Comm().IsConnected())
|
if (!remote->Comm().IsConnected())
|
||||||
{
|
{
|
||||||
if (listen_port != 0)
|
if (reverse_connect)
|
||||||
RNBLogSTDOUT ("Listening to port %i for a connection from %s...\n", listen_port, listen_host ? listen_host : "localhost");
|
{
|
||||||
if (remote->Comm().Listen(listen_host, listen_port, PortWasBoundCallbackNamedPipe, named_pipe_path) != rnb_success)
|
if (port == 0)
|
||||||
|
{
|
||||||
|
DNBLogThreaded("error: invalid port supplied for reverse connection: %i.\n", port);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (remote->Comm().Connect(host, port) != rnb_success)
|
||||||
|
{
|
||||||
|
DNBLogThreaded("Failed to reverse connect to %s:%i.\n", host, port);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (port != 0)
|
||||||
|
RNBLogSTDOUT ("Listening to port %i for a connection from %s...\n", port, host ? host : "localhost");
|
||||||
|
if (remote->Comm().Listen(host, port, PortWasBoundCallbackNamedPipe, named_pipe_path) != rnb_success)
|
||||||
{
|
{
|
||||||
RNBLogSTDERR ("Failed to get connection from a remote gdb process.\n");
|
RNBLogSTDERR ("Failed to get connection from a remote gdb process.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
remote->StartReadRemoteDataThread();
|
|
||||||
}
|
}
|
||||||
|
remote->StartReadRemoteDataThread();
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -746,6 +759,7 @@ static struct option g_long_options[] =
|
||||||
{ "working-dir", required_argument, NULL, 'W' }, // The working directory that the inferior process should have (only if debugserver launches the process)
|
{ "working-dir", required_argument, NULL, 'W' }, // The working directory that the inferior process should have (only if debugserver launches the process)
|
||||||
{ "platform", required_argument, NULL, 'p' }, // Put this executable into a remote platform mode
|
{ "platform", required_argument, NULL, 'p' }, // Put this executable into a remote platform mode
|
||||||
{ "named-pipe", required_argument, NULL, 'P' },
|
{ "named-pipe", required_argument, NULL, 'P' },
|
||||||
|
{ "reverse-connect", no_argument, NULL, 'R' },
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -801,6 +815,7 @@ main (int argc, char *argv[])
|
||||||
useconds_t waitfor_interval = 1000; // Time in usecs between process lists polls when waiting for a process by name, default 1 msec.
|
useconds_t waitfor_interval = 1000; // Time in usecs between process lists polls when waiting for a process by name, default 1 msec.
|
||||||
useconds_t waitfor_duration = 0; // Time in seconds to wait for a process by name, 0 means wait forever.
|
useconds_t waitfor_duration = 0; // Time in seconds to wait for a process by name, 0 means wait forever.
|
||||||
bool no_stdio = false;
|
bool no_stdio = false;
|
||||||
|
bool reverse_connect = false; // Set to true by an option to indicate we should reverse connect to the host:port supplied as the first debugserver argument
|
||||||
|
|
||||||
#if !defined (DNBLOG_ENABLED)
|
#if !defined (DNBLOG_ENABLED)
|
||||||
compile_options += "(no-logging) ";
|
compile_options += "(no-logging) ";
|
||||||
|
@ -997,6 +1012,9 @@ main (int argc, char *argv[])
|
||||||
// Do nothing, native regs is the default these days
|
// Do nothing, native regs is the default these days
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'R':
|
||||||
|
reverse_connect = true;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
DNBLogSetVerbose(1);
|
DNBLogSetVerbose(1);
|
||||||
break;
|
break;
|
||||||
|
@ -1117,8 +1135,8 @@ main (int argc, char *argv[])
|
||||||
compile_options.c_str(),
|
compile_options.c_str(),
|
||||||
RNB_ARCH);
|
RNB_ARCH);
|
||||||
|
|
||||||
std::string listen_host;
|
std::string host;
|
||||||
int listen_port = INT32_MAX;
|
int port = INT32_MAX;
|
||||||
char str[PATH_MAX];
|
char str[PATH_MAX];
|
||||||
str[0] = '\0';
|
str[0] = '\0';
|
||||||
|
|
||||||
|
@ -1131,24 +1149,24 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
// accept 'localhost:' prefix on port number
|
// accept 'localhost:' prefix on port number
|
||||||
|
|
||||||
int items_scanned = ::sscanf (argv[0], "%[^:]:%i", str, &listen_port);
|
int items_scanned = ::sscanf (argv[0], "%[^:]:%i", str, &port);
|
||||||
if (items_scanned == 2)
|
if (items_scanned == 2)
|
||||||
{
|
{
|
||||||
listen_host = str;
|
host = str;
|
||||||
DNBLogDebug("host = '%s' port = %i", listen_host.c_str(), listen_port);
|
DNBLogDebug("host = '%s' port = %i", host.c_str(), port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No hostname means "localhost"
|
// No hostname means "localhost"
|
||||||
int items_scanned = ::sscanf (argv[0], "%i", &listen_port);
|
int items_scanned = ::sscanf (argv[0], "%i", &port);
|
||||||
if (items_scanned == 1)
|
if (items_scanned == 1)
|
||||||
{
|
{
|
||||||
listen_host = "localhost";
|
host = "localhost";
|
||||||
DNBLogDebug("host = '%s' port = %i", listen_host.c_str(), listen_port);
|
DNBLogDebug("host = '%s' port = %i", host.c_str(), port);
|
||||||
}
|
}
|
||||||
else if (argv[0][0] == '/')
|
else if (argv[0][0] == '/')
|
||||||
{
|
{
|
||||||
listen_port = INT32_MAX;
|
port = INT32_MAX;
|
||||||
strncpy(str, argv[0], sizeof(str));
|
strncpy(str, argv[0], sizeof(str));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1263,9 +1281,9 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (listen_port != INT32_MAX)
|
if (port != INT32_MAX)
|
||||||
{
|
{
|
||||||
if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
|
if (!ConnectRemote (remote, host.c_str(), port, reverse_connect, named_pipe_path.c_str()))
|
||||||
mode = eRNBRunLoopModeExit;
|
mode = eRNBRunLoopModeExit;
|
||||||
}
|
}
|
||||||
else if (str[0] == '/')
|
else if (str[0] == '/')
|
||||||
|
@ -1376,9 +1394,9 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
if (mode != eRNBRunLoopModeExit)
|
if (mode != eRNBRunLoopModeExit)
|
||||||
{
|
{
|
||||||
if (listen_port != INT32_MAX)
|
if (port != INT32_MAX)
|
||||||
{
|
{
|
||||||
if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
|
if (!ConnectRemote (remote, host.c_str(), port, reverse_connect, named_pipe_path.c_str()))
|
||||||
mode = eRNBRunLoopModeExit;
|
mode = eRNBRunLoopModeExit;
|
||||||
}
|
}
|
||||||
else if (str[0] == '/')
|
else if (str[0] == '/')
|
||||||
|
@ -1401,9 +1419,9 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
if (mode == eRNBRunLoopModeInferiorExecuting)
|
if (mode == eRNBRunLoopModeInferiorExecuting)
|
||||||
{
|
{
|
||||||
if (listen_port != INT32_MAX)
|
if (port != INT32_MAX)
|
||||||
{
|
{
|
||||||
if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
|
if (!ConnectRemote (remote, host.c_str(), port, reverse_connect, named_pipe_path.c_str()))
|
||||||
mode = eRNBRunLoopModeExit;
|
mode = eRNBRunLoopModeExit;
|
||||||
}
|
}
|
||||||
else if (str[0] == '/')
|
else if (str[0] == '/')
|
||||||
|
@ -1428,9 +1446,9 @@ main (int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case eRNBRunLoopModePlatformMode:
|
case eRNBRunLoopModePlatformMode:
|
||||||
if (listen_port != INT32_MAX)
|
if (port != INT32_MAX)
|
||||||
{
|
{
|
||||||
if (!StartListening (remote, listen_host.c_str(), listen_port, named_pipe_path.c_str()))
|
if (!ConnectRemote (remote, host.c_str(), port, reverse_connect, named_pipe_path.c_str()))
|
||||||
mode = eRNBRunLoopModeExit;
|
mode = eRNBRunLoopModeExit;
|
||||||
}
|
}
|
||||||
else if (str[0] == '/')
|
else if (str[0] == '/')
|
||||||
|
|
|
@ -220,9 +220,6 @@ main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
|
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
|
||||||
if (conn_ap.get())
|
if (conn_ap.get())
|
||||||
{
|
|
||||||
std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
|
|
||||||
if (conn_ap.get())
|
|
||||||
{
|
{
|
||||||
std::string connect_url ("listen://");
|
std::string connect_url ("listen://");
|
||||||
connect_url.append(host_and_port);
|
connect_url.append(host_and_port);
|
||||||
|
@ -234,7 +231,6 @@ main (int argc, char *argv[])
|
||||||
gdb_server.SetConnection (conn_ap.release());
|
gdb_server.SetConnection (conn_ap.release());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (gdb_server.IsConnected())
|
if (gdb_server.IsConnected())
|
||||||
{
|
{
|
||||||
|
|
|
@ -261,25 +261,19 @@ main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
|
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
|
||||||
if (conn_ap.get())
|
if (conn_ap.get())
|
||||||
{
|
|
||||||
for (int j = 0; j < listen_host_port.size(); j++)
|
|
||||||
{
|
|
||||||
char c = listen_host_port[j];
|
|
||||||
if (c > '9' || c < '0')
|
|
||||||
printf("WARNING: passing anything but a number as argument to --listen will most probably make connecting impossible.\n");
|
|
||||||
}
|
|
||||||
std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
|
|
||||||
if (conn_ap.get())
|
|
||||||
{
|
{
|
||||||
std::string connect_url ("listen://");
|
std::string connect_url ("listen://");
|
||||||
connect_url.append(listen_host_port.c_str());
|
connect_url.append(listen_host_port.c_str());
|
||||||
|
|
||||||
printf ("Listening for a connection on %s...\n", listen_host_port.c_str());
|
printf ("Listening for a connection from %s...\n", listen_host_port.c_str());
|
||||||
if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)
|
if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)
|
||||||
{
|
{
|
||||||
printf ("Connection established.\n");
|
printf ("Connection established.\n");
|
||||||
gdb_server.SetConnection (conn_ap.release());
|
gdb_server.SetConnection (conn_ap.release());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf ("error: %s\n", error.AsCString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue