[Lldb-commits] [lldb] r246574 - Make remote-android platform to use dynamic local tcp ports when forwarding device ports.

Oleksiy Vyalov via lldb-commits lldb-commits at lists.llvm.org
Tue Sep 1 12:02:14 PDT 2015


Author: ovyalov
Date: Tue Sep  1 14:02:14 2015
New Revision: 246574

URL: http://llvm.org/viewvc/llvm-project?rev=246574&view=rev
Log:
Make remote-android platform to use dynamic local tcp ports when forwarding device ports.

http://reviews.llvm.org/D12510



Modified:
    lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp
    lldb/trunk/source/Plugins/Platform/Android/AdbClient.h
    lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
    lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h

Modified: lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp?rev=246574&r1=246573&r2=246574&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp Tue Sep  1 14:02:14 2015
@@ -131,10 +131,10 @@ AdbClient::GetDevices (DeviceIDList &dev
 }
 
 Error
-AdbClient::SetPortForwarding (const uint16_t port)
+AdbClient::SetPortForwarding (const uint16_t local_port, const uint16_t remote_port)
 {
     char message[48];
-    snprintf (message, sizeof (message), "forward:tcp:%d;tcp:%d", port, port);
+    snprintf (message, sizeof (message), "forward:tcp:%d;tcp:%d", local_port, remote_port);
 
     const auto error = SendDeviceMessage (message);
     if (error.Fail ())
@@ -144,10 +144,10 @@ AdbClient::SetPortForwarding (const uint
 }
 
 Error
-AdbClient::DeletePortForwarding (const uint16_t port)
+AdbClient::DeletePortForwarding (const uint16_t local_port)
 {
     char message[32];
-    snprintf (message, sizeof (message), "killforward:tcp:%d", port);
+    snprintf (message, sizeof (message), "killforward:tcp:%d", local_port);
 
     const auto error = SendDeviceMessage (message);
     if (error.Fail ())

Modified: lldb/trunk/source/Plugins/Platform/Android/AdbClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Android/AdbClient.h?rev=246574&r1=246573&r2=246574&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/AdbClient.h (original)
+++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.h Tue Sep  1 14:02:14 2015
@@ -48,10 +48,10 @@ public:
     GetDevices (DeviceIDList &device_list);
 
     Error
-    SetPortForwarding (const uint16_t port);
+    SetPortForwarding (const uint16_t local_port, const uint16_t remote_port);
 
     Error
-    DeletePortForwarding (const uint16_t port);
+    DeletePortForwarding (const uint16_t local_port);
 
     Error
     PullFile (const FileSpec &remote_file, const FileSpec &local_file);

Modified: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp?rev=246574&r1=246573&r2=246574&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp Tue Sep  1 14:02:14 2015
@@ -10,6 +10,7 @@
 // Other libraries and framework includes
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Host/Socket.h"
 
 // Project includes
 #include "AdbClient.h"
@@ -25,7 +26,7 @@ using namespace platform_android;
 static const lldb::pid_t g_remote_platform_pid = 0; // Alias for the process id of lldb-platform
 
 static Error
-ForwardPortWithAdb (uint16_t port, std::string& device_id)
+ForwardPortWithAdb (const uint16_t local_port, const uint16_t remote_port, std::string& device_id)
 {
     Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
 
@@ -38,14 +39,27 @@ ForwardPortWithAdb (uint16_t port, std::
     if (log)
         log->Printf("Connected to Android device \"%s\"", device_id.c_str ());
 
-    return adb.SetPortForwarding(port);
+    return adb.SetPortForwarding(local_port, remote_port);
 }
 
 static Error
-DeleteForwardPortWithAdb (uint16_t port, const std::string& device_id)
+DeleteForwardPortWithAdb (uint16_t local_port, const std::string& device_id)
 {
     AdbClient adb (device_id);
-    return adb.DeletePortForwarding (port);
+    return adb.DeletePortForwarding (local_port);
+}
+
+static Error
+FindUnusedPort (uint16_t& port)
+{
+    Socket* socket = nullptr;
+    auto error = Socket::TcpListen ("localhost:0", false, socket, nullptr);
+    if (error.Success ())
+    {
+        port = socket->GetLocalPortNumber ();
+        delete socket;
+    }
+    return error;
 }
 
 PlatformAndroidRemoteGDBServer::PlatformAndroidRemoteGDBServer ()
@@ -61,17 +75,13 @@ PlatformAndroidRemoteGDBServer::~Platfor
 uint16_t
 PlatformAndroidRemoteGDBServer::LaunchGDBserverAndGetPort (lldb::pid_t &pid)
 {
-    uint16_t port = m_gdb_client.LaunchGDBserverAndGetPort (pid, "127.0.0.1");
-    if (port == 0)
-        return port;
-
-    Error error = ForwardPortWithAdb(port, m_device_id);
-    if (error.Fail ())
-        return 0;
-
-    m_port_forwards[pid] = port;
-
-    return port;
+    uint16_t remote_port = m_gdb_client.LaunchGDBserverAndGetPort (pid, "127.0.0.1");
+    if (remote_port == 0)
+        return remote_port;
+
+    uint16_t local_port = 0;
+    auto error = SetPortForwarding (pid, remote_port, local_port);
+    return error.Success() ? local_port : 0;
 }
 
 bool
@@ -89,21 +99,28 @@ PlatformAndroidRemoteGDBServer::ConnectR
     if (args.GetArgumentCount() != 1)
         return Error("\"platform connect\" takes a single argument: <connect-url>");
 
-    int port;
+    int remote_port;
     std::string scheme, host, path;
     const char *url = args.GetArgumentAtIndex (0);
     if (!url)
         return Error("URL is null.");
-    if (!UriParser::Parse (url, scheme, host, port, path))
+    if (!UriParser::Parse (url, scheme, host, remote_port, path))
         return Error("Invalid URL: %s", url);
     if (scheme == "adb")
         m_device_id = host;
 
-    Error error = ForwardPortWithAdb(port, m_device_id);
-    if (error.Fail())
+    uint16_t local_port = 0;
+    auto error = SetPortForwarding (g_remote_platform_pid, remote_port, local_port);
+    if (error.Fail ())
         return error;
 
-    m_port_forwards[g_remote_platform_pid] = port;
+    const std::string new_url = MakeUrl(
+        scheme.c_str(), host.c_str(), local_port, path.c_str());
+    args.ReplaceArgumentAtIndex (0, new_url.c_str ());
+
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+    if (log)
+        log->Printf("Rewritten URL: %s", new_url.c_str());
 
     error = PlatformRemoteGDBServer::ConnectRemote(args);
     if (error.Fail ())
@@ -138,10 +155,39 @@ PlatformAndroidRemoteGDBServer::DeleteFo
     m_port_forwards.erase(it);
 }
 
+Error
+PlatformAndroidRemoteGDBServer::SetPortForwarding(const lldb::pid_t pid,
+                                                  const uint16_t remote_port,
+                                                  uint16_t &local_port)
+{
+    static const int kAttempsNum = 5;
+
+    Error error;
+    // There is a race possibility that somebody will occupy
+    // a port while we're in between FindUnusedPort and ForwardPortWithAdb -
+    // adding the loop to mitigate such problem.
+    for (auto i = 0; i < kAttempsNum; ++i)
+    {
+        error = FindUnusedPort(local_port);
+        if (error.Fail())
+            return error;
+
+        error = ForwardPortWithAdb(local_port, remote_port, m_device_id);
+        if (error.Success())
+        {
+            m_port_forwards[pid] = local_port;
+            break;
+        }
+    }
+
+    return error;
+}
+
 std::string
-PlatformAndroidRemoteGDBServer::MakeServerUrl(const char* scheme,
-                                              const char* hostname,
-                                              uint16_t port)
+PlatformAndroidRemoteGDBServer::MakeUrl(const char* scheme,
+                                        const char* hostname,
+                                        uint16_t port,
+                                        const char* path)
 {
     std::ostringstream hostname_str;
     if (!strcmp(scheme, "adb"))
@@ -149,7 +195,8 @@ PlatformAndroidRemoteGDBServer::MakeServ
     else
         hostname_str << hostname;
 
-    return PlatformRemoteGDBServer::MakeServerUrl(scheme,
-                                                  hostname_str.str().c_str(),
-                                                  port);
+    return PlatformRemoteGDBServer::MakeUrl(scheme,
+                                            hostname_str.str().c_str(),
+                                            port,
+                                            path);
 }

Modified: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h?rev=246574&r1=246573&r2=246574&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h Tue Sep  1 14:02:14 2015
@@ -50,9 +50,13 @@ protected:
     DeleteForwardPort (lldb::pid_t pid);
 
     std::string
-    MakeServerUrl(const char* scheme,
-                  const char* hostname,
-                  uint16_t port) override;
+    MakeUrl(const char* scheme,
+            const char* hostname,
+            uint16_t port,
+            const char* path) override;
+
+    Error
+    SetPortForwarding(const lldb::pid_t pid, const uint16_t remote_port, uint16_t &local_port);
 
 private:
     DISALLOW_COPY_AND_ASSIGN (PlatformAndroidRemoteGDBServer);

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp?rev=246574&r1=246573&r2=246574&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp Tue Sep  1 14:02:14 2015
@@ -963,17 +963,21 @@ PlatformRemoteGDBServer::MakeGdbServerUr
     const char *port_offset_c_str = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET");
     int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0;
 
-    return MakeServerUrl(override_scheme ? override_scheme : platform_scheme.c_str(),
-                         override_hostname ? override_hostname : platform_hostname.c_str(),
-                         port + port_offset);
+    return MakeUrl(override_scheme ? override_scheme : platform_scheme.c_str(),
+                   override_hostname ? override_hostname : platform_hostname.c_str(),
+                   port + port_offset,
+                   nullptr);
 }
 
 std::string
-PlatformRemoteGDBServer::MakeServerUrl(const char* scheme,
+PlatformRemoteGDBServer::MakeUrl(const char* scheme,
                                        const char* hostname,
-                                       uint16_t port)
+                                       uint16_t port,
+                                       const char* path)
 {
     StreamString result;
     result.Printf("%s://%s:%u", scheme, hostname, port);
+    if (path)
+        result.Write(path, strlen(path));
     return result.GetString();
 }

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h?rev=246574&r1=246573&r2=246574&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h Tue Sep  1 14:02:14 2015
@@ -235,9 +235,10 @@ protected:
     KillSpawnedProcess (lldb::pid_t pid);
 
     virtual std::string
-    MakeServerUrl(const char* scheme,
-                  const char* hostname,
-                  uint16_t port);
+    MakeUrl(const char* scheme,
+            const char* hostname,
+            uint16_t port,
+            const char* path);
 
 private:
     std::string




More information about the lldb-commits mailing list