[Lldb-commits] [lldb] r236321 - Support remote-android with multiple connected devices.

Chaoren Lin chaorenl at google.com
Fri May 1 09:49:28 PDT 2015


Author: chaoren
Date: Fri May  1 11:49:28 2015
New Revision: 236321

URL: http://llvm.org/viewvc/llvm-project?rev=236321&view=rev
Log:
Support remote-android with multiple connected devices.

Summary:
This change introduces a new URL scheme for `platform connect`:
```
adb://device-id:port
```

Reviewers: vharron, tberghammer, clayborg, ovyalov

Reviewed By: ovyalov

Subscribers: tberghammer, lldb-commits

Differential Revision: http://reviews.llvm.org/D9358

Modified:
    lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp
    lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp
    lldb/trunk/source/Plugins/Platform/Android/AdbClient.h
    lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp
    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/Host/posix/ConnectionFileDescriptorPosix.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp?rev=236321&r1=236320&r2=236321&view=diff
==============================================================================
--- lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp (original)
+++ lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp Fri May  1 11:49:28 2015
@@ -166,6 +166,14 @@ ConnectionFileDescriptor::Connect(const
             // unix://SOCKNAME
             return NamedSocketAccept(s + strlen("unix-accept://"), error_ptr);
         }
+        else if (strstr(s, "adb://") == s)
+        {
+            int port = -1;
+            sscanf(s, "adb://%*[^:]:%d", &port);
+            char host_and_port[sizeof("localhost:65535")];
+            snprintf(host_and_port, sizeof(host_and_port), "localhost:%d", port);
+            return ConnectTCP(host_and_port, error_ptr);
+        }
         else if (strstr(s, "connect://") == s)
         {
             return ConnectTCP(s + strlen("connect://"), error_ptr);

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=236321&r1=236320&r2=236321&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp Fri May  1 11:49:28 2015
@@ -31,27 +31,28 @@ const char * kFAIL = "FAIL";
 }  // namespace
 
 Error
-AdbClient::CreateByDeviceID (const char* device_id, AdbClient &adb)
+AdbClient::CreateByDeviceID(const std::string &device_id, AdbClient &adb)
 {
     DeviceIDList connect_devices;
-    auto error = adb.GetDevices (connect_devices);
-    if (error.Fail ())
+    auto error = adb.GetDevices(connect_devices);
+    if (error.Fail())
         return error;
 
-    if (device_id)
+    if (device_id.empty())
     {
-        auto find_it = std::find(connect_devices.begin (), connect_devices.end (), device_id);
-        if (find_it == connect_devices.end ())
-            return Error ("Device \"%s\" not found", device_id);
+        if (connect_devices.size() != 1)
+            return Error("Expected a single connected device, got instead %" PRIu64,
+                    static_cast<uint64_t>(connect_devices.size()));
 
-        adb.SetDeviceID (*find_it);
+        adb.SetDeviceID(connect_devices.front());
     }
     else
     {
-        if (connect_devices.size () != 1)
-            return Error ("Expected a single connected device, got instead %" PRIu64, static_cast<uint64_t>(connect_devices.size ()));
+        auto find_it = std::find(connect_devices.begin(), connect_devices.end(), device_id);
+        if (find_it == connect_devices.end())
+            return Error("Device \"%s\" not found", device_id.c_str());
 
-        adb.SetDeviceID (connect_devices.front ());
+        adb.SetDeviceID(*find_it);
     }
     return error;
 }

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=236321&r1=236320&r2=236321&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/AdbClient.h (original)
+++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.h Fri May  1 11:49:28 2015
@@ -32,7 +32,7 @@ public:
     using DeviceIDList = std::list<std::string>;
 
     static Error
-    CreateByDeviceID (const char* device_id, AdbClient &adb);
+    CreateByDeviceID(const std::string &device_id, AdbClient &adb);
 
     AdbClient () = default;
     explicit AdbClient (const std::string &device_id);

Modified: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp?rev=236321&r1=236320&r2=236321&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp Fri May  1 11:49:28 2015
@@ -13,6 +13,7 @@
 #include "lldb/Core/Log.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Host/HostInfo.h"
+#include "Utility/UriParser.h"
 
 // Project includes
 #include "AdbClient.h"
@@ -171,9 +172,9 @@ PlatformAndroid::GetPluginName()
 }
 
 Error
-PlatformAndroid::ConnectRemote (Args& args)
+PlatformAndroid::ConnectRemote(Args& args)
 {
-    m_device_id.clear ();
+    m_device_id.clear();
 
     if (IsHost())
     {
@@ -183,17 +184,25 @@ PlatformAndroid::ConnectRemote (Args& ar
     if (!m_remote_platform_sp)
         m_remote_platform_sp = PlatformSP(new PlatformAndroidRemoteGDBServer());
 
-    auto error = PlatformLinux::ConnectRemote (args);
-    if (error.Success ())
+    int 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))
+        return Error("Invalid URL: %s", url);
+    if (scheme == "adb")
+        m_device_id = host;
+
+    auto error = PlatformLinux::ConnectRemote(args);
+    if (error.Success())
     {
-        // Fetch the device list from ADB and if only 1 device found then use that device
-        // TODO: Handle the case when more device is available
         AdbClient adb;
-        error = AdbClient::CreateByDeviceID (nullptr, adb);
-        if (error.Fail ())
+        error = AdbClient::CreateByDeviceID(m_device_id, adb);
+        if (error.Fail())
             return error;
 
-        m_device_id = adb.GetDeviceID ();
+        m_device_id = adb.GetDeviceID();
     }
     return error;
 }

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=236321&r1=236320&r2=236321&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp Fri May  1 11:49:28 2015
@@ -27,18 +27,16 @@ ForwardPortWithAdb (uint16_t port, std::
 {
     Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
 
-    // Fetch the device list from ADB and if only 1 device found then use that device
-    // TODO: Handle the case when more device is available
     AdbClient adb;
-    auto error = AdbClient::CreateByDeviceID (nullptr, adb);
+    auto error = AdbClient::CreateByDeviceID(device_id, adb);
     if (error.Fail ())
         return error;
 
-    device_id = adb.GetDeviceID ();
+    device_id = adb.GetDeviceID();
     if (log)
         log->Printf("Connected to Android device \"%s\"", device_id.c_str ());
 
-    return adb.SetPortForwarding (port);
+    return adb.SetPortForwarding(port);
 }
 
 static Error
@@ -55,9 +53,7 @@ PlatformAndroidRemoteGDBServer::Platform
 PlatformAndroidRemoteGDBServer::~PlatformAndroidRemoteGDBServer ()
 {
     for (const auto& it : m_port_forwards)
-    {
-        DeleteForwardPortWithAdb (it.second.first, it.second.second);
-    }
+        DeleteForwardPortWithAdb(it.second, m_device_id);
 }
 
 uint16_t
@@ -67,12 +63,11 @@ PlatformAndroidRemoteGDBServer::LaunchGD
     if (port == 0)
         return port;
 
-    std::string device_id;
-    Error error = ForwardPortWithAdb (port, device_id);
+    Error error = ForwardPortWithAdb(port, m_device_id);
     if (error.Fail ())
         return 0;
 
-    m_port_forwards[pid] = std::make_pair (port, device_id);
+    m_port_forwards[pid] = port;
 
     return port;
 }
@@ -87,23 +82,28 @@ PlatformAndroidRemoteGDBServer::KillSpaw
 Error
 PlatformAndroidRemoteGDBServer::ConnectRemote (Args& args)
 {
-    if (args.GetArgumentCount () != 1)
-        return Error ("\"platform connect\" takes a single argument: <connect-url>");
-  
+    m_device_id.clear();
+
+    if (args.GetArgumentCount() != 1)
+        return Error("\"platform connect\" takes a single argument: <connect-url>");
+
     int 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))
-        return Error ("invalid uri");
+        return Error("Invalid URL: %s", url);
+    if (scheme == "adb")
+        m_device_id = host;
 
-    std::string device_id;
-    Error error = ForwardPortWithAdb (port, device_id);
-    if (error.Fail ())
+    Error error = ForwardPortWithAdb(port, m_device_id);
+    if (error.Fail())
         return error;
 
-    m_port_forwards[g_remote_platform_pid] = std::make_pair (port, device_id);
+    m_port_forwards[g_remote_platform_pid] = port;
 
-    error = PlatformRemoteGDBServer::ConnectRemote (args);
+    error = PlatformRemoteGDBServer::ConnectRemote(args);
     if (error.Fail ())
         DeleteForwardPort (g_remote_platform_pid);
 
@@ -120,18 +120,18 @@ PlatformAndroidRemoteGDBServer::Disconne
 void
 PlatformAndroidRemoteGDBServer::DeleteForwardPort (lldb::pid_t pid)
 {
-    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
 
-    auto it = m_port_forwards.find (pid);
-    if (it == m_port_forwards.end ())
+    auto it = m_port_forwards.find(pid);
+    if (it == m_port_forwards.end())
         return;
 
-    const auto& forward_val = it->second;
-    const auto error = DeleteForwardPortWithAdb (forward_val.first, forward_val.second);
-    if (error.Fail ()) {
+    const auto port = it->second;
+    const auto error = DeleteForwardPortWithAdb(port, m_device_id);
+    if (error.Fail()) {
         if (log)
-            log->Printf ("Failed to delete port forwarding (pid=%" PRIu64 ", port=%d, device=%s): %s",
-                         pid, forward_val.first, forward_val.second.c_str (), error.AsCString ());
+            log->Printf("Failed to delete port forwarding (pid=%" PRIu64 ", port=%d, device=%s): %s",
+                         pid, port, m_device_id.c_str(), error.AsCString());
     }
-    m_port_forwards.erase (it);
+    m_port_forwards.erase(it);
 }

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=236321&r1=236320&r2=236321&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h Fri May  1 11:49:28 2015
@@ -37,7 +37,8 @@ public:
     DisconnectRemote () override;
 
 protected:
-    std::map<lldb::pid_t, std::pair<uint16_t, std::string>> m_port_forwards;
+    std::string m_device_id;
+    std::map<lldb::pid_t, uint16_t> m_port_forwards;
 
     uint16_t
     LaunchGDBserverAndGetPort (lldb::pid_t &pid) override;

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=236321&r1=236320&r2=236321&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp Fri May  1 11:49:28 2015
@@ -40,13 +40,18 @@ using namespace lldb_private::platform_g
 
 static bool g_initialized = false;
 
-static std::string MakeGdbServerUrl (const std::string &platform_hostname, uint16_t port)
+static std::string MakeGdbServerUrl(
+        const std::string &platform_scheme,
+        const std::string &platform_hostname,
+        uint16_t port)
 {
+    const char *override_scheme = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME");
     const char *override_hostname = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
     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;
     StreamString result;
-    result.Printf("connect://%s:%u",
+    result.Printf("%s://%s:%u",
+            override_scheme ? override_scheme : platform_scheme.c_str(),
             override_hostname ? override_hostname : platform_hostname.c_str(),
             port + port_offset);
     return result.GetString();
@@ -375,17 +380,15 @@ PlatformRemoteGDBServer::ConnectRemote (
     {
         if (args.GetArgumentCount() == 1)
         {
-            const char *url = args.GetArgumentAtIndex(0);
-            m_gdb_client.SetConnection (new ConnectionFileDescriptor());
+            m_gdb_client.SetConnection(new ConnectionFileDescriptor());
             // we're going to reuse the hostname when we connect to the debugserver
-            std::string scheme;
             int port;
             std::string path;
-            if ( !UriParser::Parse(url, scheme, m_platform_hostname, port, path) )
-            {
-                error.SetErrorString("invalid uri");
-                return error;
-            }
+            const char *url = args.GetArgumentAtIndex(0);
+            if (!url)
+                return Error("URL is null.");
+            if (!UriParser::Parse(url, m_platform_scheme, m_platform_hostname, port, path))
+                return Error("Invalid URL: %s", url);
 
             const ConnectionStatus status = m_gdb_client.Connect(url, &error);
             if (status == eConnectionStatusSuccess)
@@ -624,7 +627,8 @@ PlatformRemoteGDBServer::DebugProcess (P
                     
                     if (process_sp)
                     {
-                        std::string connect_url = MakeGdbServerUrl(m_platform_hostname, port);
+                        std::string connect_url =
+                            MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port);
                         error = process_sp->ConnectRemote (nullptr, connect_url.c_str());
                         // Retry the connect remote one time...
                         if (error.Fail())
@@ -719,7 +723,8 @@ PlatformRemoteGDBServer::Attach (Process
                     
                     if (process_sp)
                     {
-                        std::string connect_url = MakeGdbServerUrl(m_platform_hostname, port);
+                        std::string connect_url =
+                            MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port);
                         error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
                         if (error.Success())
                         {

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=236321&r1=236320&r2=236321&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h Fri May  1 11:49:28 2015
@@ -216,6 +216,7 @@ public:
 protected:
     process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client;
     std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to
+    std::string m_platform_scheme;
     std::string m_platform_hostname;
 
     // Launch the lldb-gdbserver on the remote host and return the port it is listening on or 0 on





More information about the lldb-commits mailing list