[Lldb-commits] [lldb] r237640 - Use ADB pull to download modules from android target.

Oleksiy Vyalov ovyalov at google.com
Mon May 18 16:44:06 PDT 2015


Author: ovyalov
Date: Mon May 18 18:44:06 2015
New Revision: 237640

URL: http://llvm.org/viewvc/llvm-project?rev=237640&view=rev
Log:
Use ADB pull to download modules from android target.

http://reviews.llvm.org/D9816


Modified:
    lldb/trunk/include/lldb/Target/Platform.h
    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/PlatformAndroid.h

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=237640&r1=237639&r2=237640&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Mon May 18 18:44:06 2015
@@ -1139,7 +1139,7 @@ class ModuleCache;
                              const FileSpecList *module_search_paths_ptr,
                              Platform &remote_platform);
 
-        Error
+        virtual Error
         DownloadModuleSlice (const FileSpec& src_file_spec,
                              const uint64_t src_offset,
                              const uint64_t src_size,

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=237640&r1=237639&r2=237640&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp Mon May 18 18:44:06 2015
@@ -8,14 +8,22 @@
 //===----------------------------------------------------------------------===//
 
 // Other libraries and framework includes
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataEncoder.h"
+#include "lldb/Core/DataExtractor.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/FileUtilities.h"
 
 // Project includes
 #include "AdbClient.h"
 
+#include <limits.h>
+
 #include <algorithm>
+#include <fstream>
 #include <sstream>
 
 using namespace lldb;
@@ -24,9 +32,10 @@ using namespace lldb_private::platform_a
 
 namespace {
 
-const uint32_t kConnTimeout = 10000; // 10 ms
+const uint32_t kReadTimeout = 1000000; // 1 second
 const char * kOKAY = "OKAY";
 const char * kFAIL = "FAIL";
+const size_t kSyncPacketLen = 8;
 
 }  // namespace
 
@@ -63,7 +72,7 @@ AdbClient::AdbClient (const std::string
 }
 
 void
-AdbClient::SetDeviceID (const std::string& device_id)
+AdbClient::SetDeviceID (const std::string &device_id)
 {
     m_device_id = device_id;
 }
@@ -96,10 +105,10 @@ AdbClient::GetDevices (DeviceIDList &dev
     if (error.Fail ())
         return error;
 
-    std::string in_buffer;
+    std::vector<char> in_buffer;
     error = ReadMessage (in_buffer);
 
-    llvm::StringRef response (in_buffer);
+    llvm::StringRef response (&in_buffer[0], in_buffer.size ());
     llvm::SmallVector<llvm::StringRef, 4> devices;
     response.split (devices, "\n", -1, false);
 
@@ -136,11 +145,15 @@ AdbClient::DeletePortForwarding (const u
 }
 
 Error
-AdbClient::SendMessage (const std::string &packet)
+AdbClient::SendMessage (const std::string &packet, const bool reconnect)
 {
-    auto error = Connect ();
-    if (error.Fail ())
-        return error;
+    Error error;
+    if (reconnect)
+    {
+        error = Connect ();
+        if (error.Fail ())
+            return error;
+    }
 
     char length_buffer[5];
     snprintf (length_buffer, sizeof (length_buffer), "%04x", static_cast<int>(packet.size ()));
@@ -164,26 +177,24 @@ AdbClient::SendDeviceMessage (const std:
 }
 
 Error
-AdbClient::ReadMessage (std::string &message)
+AdbClient::ReadMessage (std::vector<char> &message)
 {
     message.clear ();
 
     char buffer[5];
     buffer[4] = 0;
 
-    Error error;
-    ConnectionStatus status;
-
-    m_conn.Read (buffer, 4, kConnTimeout, status, &error);
+    auto error = ReadAllBytes (buffer, 4);
     if (error.Fail ())
         return error;
 
     unsigned int packet_len = 0;
     sscanf (buffer, "%x", &packet_len);
-    std::string result (packet_len, 0);
-    m_conn.Read (&result[0], packet_len, kConnTimeout, status, &error);
-    if (error.Success ())
-        result.swap (message);
+
+    message.resize (packet_len, 0);
+    error = ReadAllBytes (&message[0], packet_len);
+    if (error.Fail ())
+        message.clear ();
 
     return error;
 }
@@ -191,31 +202,169 @@ AdbClient::ReadMessage (std::string &mes
 Error
 AdbClient::ReadResponseStatus()
 {
-    char buffer[5];
+    char response_id[5];
 
     static const size_t packet_len = 4;
-    buffer[packet_len] = 0;
+    response_id[packet_len] = 0;
+
+    auto error = ReadAllBytes (response_id, packet_len);
+    if (error.Fail ())
+        return error;
+
+    if (strncmp (response_id, kOKAY, packet_len) != 0)
+        return GetResponseError (response_id);
+
+    return error;
+}
+
+Error
+AdbClient::GetResponseError (const char *response_id)
+{
+    if (strcmp (response_id, kFAIL) != 0)
+        return Error ("Got unexpected response id from adb: \"%s\"", response_id);
+
+    std::vector<char> error_message;
+    auto error = ReadMessage (error_message);
+    if (error.Success ())
+        error.SetErrorString (std::string (&error_message[0], error_message.size ()).c_str ());
+
+    return error;
+}
+
+Error
+AdbClient::SwitchDeviceTransport ()
+{
+    std::ostringstream msg;
+    msg << "host:transport:" << m_device_id;
+
+    auto error = SendMessage (msg.str ());
+    if (error.Fail ())
+        return error;
+
+    return ReadResponseStatus ();
+}
+
+Error
+AdbClient::PullFile (const char *remote_file, const char *local_file)
+{
+    auto error = SwitchDeviceTransport ();
+    if (error.Fail ())
+        return Error ("Failed to switch to device transport: %s", error.AsCString ());
+
+    error = Sync ();
+    if (error.Fail ())
+        return Error ("Sync failed: %s", error.AsCString ());
+
+    llvm::FileRemover local_file_remover (local_file);
+
+    std::ofstream dst (local_file, std::ios::out | std::ios::binary);
+    if (!dst.is_open ())
+        return Error ("Unable to open local file %s", local_file);
+
+    error = SendSyncRequest ("RECV", strlen(remote_file), remote_file);
+    if (error.Fail ())
+        return error;
+
+    std::vector<char> chunk;
+    bool eof = false;
+    while (!eof)
+    {
+        error = PullFileChunk (chunk, eof);
+        if (error.Fail ())
+            return Error ("Failed to read file chunk: %s", error.AsCString ());
+        if (!eof)
+            dst.write (&chunk[0], chunk.size ());
+    }
+
+    local_file_remover.releaseFile ();
+    return error;
+}
+
+Error
+AdbClient::Sync ()
+{
+    auto error = SendMessage ("sync:", false);
+    if (error.Fail ())
+        return error;
+
+    return ReadResponseStatus ();
+}
+
+Error
+AdbClient::PullFileChunk (std::vector<char> &buffer, bool &eof)
+{
+    buffer.clear ();
+
+    std::string response_id;
+    uint32_t data_len;
+    auto error = ReadSyncHeader (response_id, data_len);
+    if (error.Fail ())
+        return error;
+
+    if (response_id == "DATA")
+    {
+        buffer.resize (data_len, 0);
+        error = ReadAllBytes (&buffer[0], data_len);
+        if (error.Fail ())
+            buffer.clear ();
+    }
+    else if (response_id == "DONE")
+        eof = true;
+    else
+        error = GetResponseError (response_id.c_str ());
+
+    return error;
+}
+
+Error
+AdbClient::SendSyncRequest (const char *request_id, const uint32_t data_len, const void *data)
+{
+    const DataBufferSP data_sp (new DataBufferHeap (kSyncPacketLen, 0));
+    DataEncoder encoder (data_sp, eByteOrderLittle, sizeof (void*));
+    auto offset = encoder.PutData (0, request_id, strlen(request_id));
+    encoder.PutU32 (offset, data_len);
 
     Error error;
     ConnectionStatus status;
-
-    m_conn.Read (buffer, packet_len, kConnTimeout, status, &error);
+    m_conn.Write (data_sp->GetBytes (), kSyncPacketLen, status, &error);
     if (error.Fail ())
         return error;
 
-    if (strncmp (buffer, kOKAY, packet_len) != 0)
+    m_conn.Write (data, data_len, status, &error);
+    return error;
+}
+
+Error
+AdbClient::ReadSyncHeader (std::string &response_id, uint32_t &data_len)
+{
+    char buffer[kSyncPacketLen];
+
+    auto error = ReadAllBytes (buffer, kSyncPacketLen);
+    if (error.Success ())
     {
-        if (strncmp (buffer, kFAIL, packet_len) == 0)
-        {
-            std::string error_message;
-            error = ReadMessage (error_message);
-            if (error.Fail ())
-                return error;
-            error.SetErrorString (error_message.c_str ());
-        }
-        else
-            error.SetErrorStringWithFormat ("\"%s\" expected from adb, received: \"%s\"", kOKAY, buffer);
+        response_id.assign (&buffer[0], 4);
+        DataExtractor extractor (&buffer[4], 4, eByteOrderLittle, sizeof (void*));
+        offset_t offset = 0;
+        data_len = extractor.GetU32 (&offset);
     }
 
     return error;
 }
+
+Error
+AdbClient::ReadAllBytes (void *buffer, size_t size)
+{
+    Error error;
+    ConnectionStatus status;
+    char *read_buffer = static_cast<char*>(buffer);
+
+    size_t tota_read_bytes = 0;
+    while (tota_read_bytes < size)
+    {
+        auto read_bytes = m_conn.Read (read_buffer + tota_read_bytes, size - tota_read_bytes, kReadTimeout, status, &error);
+        if (error.Fail ())
+            return error;
+        tota_read_bytes += read_bytes;
+    }
+    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=237640&r1=237639&r2=237640&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/AdbClient.h (original)
+++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.h Mon May 18 18:44:06 2015
@@ -16,6 +16,7 @@
 
 #include <list>
 #include <string>
+#include <vector>
 
 // Other libraries and framework includes
 // Project includes
@@ -49,25 +50,49 @@ public:
     Error
     DeletePortForwarding (const uint16_t port);
 
+    Error
+    PullFile (const char *remote_file, const char *local_file);
+
 private:
     Error
     Connect ();
 
     void
-    SetDeviceID (const std::string& device_id);
+    SetDeviceID (const std::string &device_id);
 
     Error
-    SendMessage (const std::string &packet);
+    SendMessage (const std::string &packet, const bool reconnect = true);
 
     Error
     SendDeviceMessage (const std::string &packet);
 
     Error
-    ReadMessage (std::string &message);
+    SendSyncRequest (const char *request_id, const uint32_t data_len, const void *data);
+
+    Error
+    ReadSyncHeader (std::string &response_id, uint32_t &data_len);
+
+    Error
+    ReadMessage (std::vector<char> &message);
+
+    Error
+    GetResponseError (const char *response_id);
 
     Error
     ReadResponseStatus ();
 
+    Error
+    SwitchDeviceTransport ();
+
+    Error
+    Sync ();
+
+    Error
+    PullFileChunk (std::vector<char> &buffer, bool &eof);
+
+    Error
+    ReadAllBytes (void *buffer, size_t size);
+
     std::string m_device_id;
     ConnectionFileDescriptor m_conn;
 };

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=237640&r1=237639&r2=237640&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp Mon May 18 18:44:06 2015
@@ -212,3 +212,16 @@ PlatformAndroid::GetCacheHostname ()
 {
     return m_device_id.c_str ();
 }
+
+Error
+PlatformAndroid::DownloadModuleSlice (const FileSpec &src_file_spec,
+                                      const uint64_t src_offset,
+                                      const uint64_t src_size,
+                                      const FileSpec &dst_file_spec)
+{
+    if (src_offset != 0)
+        return Error ("Invalid offset - %" PRIu64, src_offset);
+
+    AdbClient adb (m_device_id);
+    return adb.PullFile (src_file_spec.GetPath (false).c_str (), dst_file_spec.GetPath ().c_str ());
+}

Modified: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h?rev=237640&r1=237639&r2=237640&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h Mon May 18 18:44:06 2015
@@ -68,6 +68,12 @@ namespace platform_android {
         const char *
         GetCacheHostname () override;
 
+        Error
+        DownloadModuleSlice (const FileSpec &src_file_spec,
+                             const uint64_t src_offset,
+                             const uint64_t src_size,
+                             const FileSpec &dst_file_spec) override;
+
     private:
         std::string m_device_id;
         DISALLOW_COPY_AND_ASSIGN (PlatformAndroid);





More information about the lldb-commits mailing list