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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits