From 1e210abf9925ad08fb7c79894b4ec5ef8f0ef173 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Luka=20Marku=C5=A1i=C4=87?= Date: Wed, 26 Oct 2022 08:02:47 +0000 Subject: [PATCH] [LLDB] Make remote-android local ports configurable The local ports for `platform connect` and `attach` were always random, this allows the user to configure them. This is useful for debugging a truly remote android (when the android in question is connected to a remote server). There is a lengthier discussion on github - https://github.com/llvm/llvm-project/issues/58114 Reviewed By: clayborg Differential Revision: https://reviews.llvm.org/D136465 --- lldb/docs/use/remote.rst | 5 +++ .../Android/PlatformAndroidRemoteGDBServer.cpp | 52 +++++++++++++++------- .../Android/PlatformAndroidRemoteGDBServer.h | 3 +- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/lldb/docs/use/remote.rst b/lldb/docs/use/remote.rst index 0eb43fb..ef8847a 100644 --- a/lldb/docs/use/remote.rst +++ b/lldb/docs/use/remote.rst @@ -135,6 +135,11 @@ application needs additional files, you can transfer them using the platform commands: get-file, put-file, mkdir, etc. The environment can be prepared further using the platform shell command. +When using the "remote-android" platform, the client LLDB forwards two ports, one +for connecting to the platform, and another for connecting to the gdbserver. +The client ports are configurable through the environment variables +ANDROID_PLATFORM_PORT and ANDROID_PLATFORM_GDB_PORT, respectively. + Launching a locally built process on the remote machine ------------------------------------------------------- diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp index 2727450..7c69439 100644 --- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp @@ -90,8 +90,13 @@ bool PlatformAndroidRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid, Log *log = GetLog(LLDBLog::Platform); - auto error = - MakeConnectURL(pid, remote_port, socket_name.c_str(), connect_url); + uint16_t local_port = 0; + const char *gdbstub_port = std::getenv("ANDROID_PLATFORM_LOCAL_GDB_PORT"); + if (gdbstub_port) + local_port = std::stoi(gdbstub_port); + + auto error = MakeConnectURL(pid, local_port, remote_port, socket_name.c_str(), + connect_url); if (error.Success() && log) LLDB_LOGF(log, "gdbserver connect URL: %s", connect_url.c_str()); @@ -126,10 +131,15 @@ Status PlatformAndroidRemoteGDBServer::ConnectRemote(Args &args) { else if (parsed_url->scheme == "unix-abstract-connect") m_socket_namespace = AdbClient::UnixSocketNamespaceAbstract; + uint16_t local_port = 0; + const char *platform_local_port = std::getenv("ANDROID_PLATFORM_LOCAL_PORT"); + if (platform_local_port) + local_port = std::stoi(platform_local_port); + std::string connect_url; - auto error = - MakeConnectURL(g_remote_platform_pid, parsed_url->port.value_or(0), - parsed_url->path, connect_url); + auto error = MakeConnectURL(g_remote_platform_pid, local_port, + parsed_url->port.value_or(0), parsed_url->path, + connect_url); if (error.Fail()) return error; @@ -170,11 +180,28 @@ void PlatformAndroidRemoteGDBServer::DeleteForwardPort(lldb::pid_t pid) { } Status PlatformAndroidRemoteGDBServer::MakeConnectURL( - const lldb::pid_t pid, const uint16_t remote_port, - llvm::StringRef remote_socket_name, std::string &connect_url) { + const lldb::pid_t pid, const uint16_t local_port, + const uint16_t remote_port, llvm::StringRef remote_socket_name, + std::string &connect_url) { static const int kAttempsNum = 5; Status error; + + auto forward = [&](const uint16_t local, const uint16_t remote) { + error = ForwardPortWithAdb(local, remote, remote_socket_name, + m_socket_namespace, m_device_id); + if (error.Success()) { + m_port_forwards[pid] = local; + std::ostringstream url_str; + url_str << "connect://127.0.0.1:" << local; + connect_url = url_str.str(); + } + return error; + }; + + if (local_port != 0) + return forward(local_port, remote_port); + // 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. @@ -184,15 +211,8 @@ Status PlatformAndroidRemoteGDBServer::MakeConnectURL( if (error.Fail()) return error; - error = ForwardPortWithAdb(local_port, remote_port, remote_socket_name, - m_socket_namespace, m_device_id); - if (error.Success()) { - m_port_forwards[pid] = local_port; - std::ostringstream url_str; - url_str << "connect://127.0.0.1:" << local_port; - connect_url = url_str.str(); + if (forward(local_port, remote_port).Success()) break; - } } return error; @@ -216,7 +236,7 @@ lldb::ProcessSP PlatformAndroidRemoteGDBServer::ConnectProcess( } std::string new_connect_url; - error = MakeConnectURL(s_remote_gdbserver_fake_pid--, + error = MakeConnectURL(s_remote_gdbserver_fake_pid--, 0, parsed_url->port.value_or(0), parsed_url->path, new_connect_url); if (error.Fail()) diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h index 0b3e4c6..d385360 100644 --- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h @@ -49,7 +49,8 @@ protected: void DeleteForwardPort(lldb::pid_t pid); - Status MakeConnectURL(const lldb::pid_t pid, const uint16_t remote_port, + Status MakeConnectURL(const lldb::pid_t pid, const uint16_t local_port, + const uint16_t remote_port, llvm::StringRef remote_socket_name, std::string &connect_url); -- 2.7.4