[Lldb-commits] [lldb] r238274 - Implement and use adb push for PlatformAndroid::PutFile

Robert Flack flackr at gmail.com
Tue May 26 19:18:50 PDT 2015


Author: flackr
Date: Tue May 26 21:18:50 2015
New Revision: 238274

URL: http://llvm.org/viewvc/llvm-project?rev=238274&view=rev
Log:
Implement and use adb push for PlatformAndroid::PutFile

Using the adb push protocol is significantly faster than the current method of
sending the hex encoded file data for the remote to write to the file.

Test Plan:
Tests continue to pass - and much faster (e.g. TestSBValuePersist.py takes 10s
down from 4m51s on mac -> android)

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

Modified:
    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/source/Plugins/Platform/Android/AdbClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp?rev=238274&r1=238273&r2=238274&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp Tue May 26 21:18:50 2015
@@ -12,6 +12,7 @@
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataEncoder.h"
 #include "lldb/Core/DataExtractor.h"
+#include "lldb/Host/FileSpec.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/STLExtras.h"
@@ -36,6 +37,10 @@ const uint32_t kReadTimeout = 1000000; /
 const char * kOKAY = "OKAY";
 const char * kFAIL = "FAIL";
 const size_t kSyncPacketLen = 8;
+// Maximum size of a filesync DATA packet.
+const size_t kMaxPushData = 2*1024;
+// Default mode for pushed files.
+const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG
 
 }  // namespace
 
@@ -281,6 +286,47 @@ AdbClient::PullFile (const char *remote_
 }
 
 Error
+AdbClient::PushFile (const lldb_private::FileSpec& source, const lldb_private::FileSpec& destination)
+{
+    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 ());
+
+    std::ifstream src (source.GetPath().c_str(), std::ios::in | std::ios::binary);
+    if (!src.is_open ())
+        return Error ("Unable to open local file %s", source.GetPath().c_str());
+
+    std::stringstream file_description;
+    file_description << destination.GetPath(false).c_str() << "," << kDefaultMode;
+    std::string file_description_str = file_description.str();
+    error = SendSyncRequest ("SEND", file_description_str.length(), file_description_str.c_str());
+    if (error.Fail ())
+        return error;
+
+    char chunk[kMaxPushData];
+    while (!src.eof() && !src.read(chunk, kMaxPushData).bad())
+    {
+        size_t chunk_size = src.gcount();
+        error = SendSyncRequest("DATA", chunk_size, chunk);
+        if (error.Fail ())
+            return Error ("Failed to send file chunk: %s", error.AsCString ());
+    }
+    error = SendSyncRequest("DONE", source.GetModificationTime().seconds(), nullptr);
+    if (error.Fail ())
+        return error;
+    error = ReadResponseStatus();
+    // If there was an error reading the source file, finish the adb file
+    // transfer first so that adb isn't expecting any more data.
+    if (src.bad())
+        return Error ("Failed read on %s", source.GetPath().c_str());
+    return error;
+}
+
+Error
 AdbClient::Sync ()
 {
     auto error = SendMessage ("sync:", false);
@@ -330,7 +376,8 @@ AdbClient::SendSyncRequest (const char *
     if (error.Fail ())
         return error;
 
-    m_conn.Write (data, data_len, status, &error);
+    if (data)
+        m_conn.Write (data, data_len, status, &error);
     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=238274&r1=238273&r2=238274&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/AdbClient.h (original)
+++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.h Tue May 26 21:18:50 2015
@@ -53,6 +53,9 @@ public:
     Error
     PullFile (const char *remote_file, const char *local_file);
 
+    Error
+    PushFile (const lldb_private::FileSpec& source, const lldb_private::FileSpec& destination);
+
 private:
     Error
     Connect ();

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=238274&r1=238273&r2=238274&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp Tue May 26 21:18:50 2015
@@ -207,6 +207,21 @@ PlatformAndroid::ConnectRemote(Args& arg
     return error;
 }
 
+lldb_private::Error
+PlatformAndroid::PutFile (const lldb_private::FileSpec& source,
+                          const lldb_private::FileSpec& destination,
+                          uint32_t uid,
+                          uint32_t gid)
+{
+    if (!IsHost() && m_remote_platform_sp)
+    {
+        AdbClient adb (m_device_id);
+        // TODO: Set correct uid and gid on remote file.
+        return adb.PushFile(source, destination);
+    }
+    return PlatformLinux::PutFile(source, destination, uid, gid);
+}
+
 const char *
 PlatformAndroid::GetCacheHostname ()
 {

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=238274&r1=238273&r2=238274&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h Tue May 26 21:18:50 2015
@@ -64,7 +64,13 @@ namespace platform_android {
         Error
         ConnectRemote (Args& args) override;
 
-    protected:
+        lldb_private::Error
+        PutFile (const lldb_private::FileSpec& source,
+                 const lldb_private::FileSpec& destination,
+                 uint32_t uid = UINT32_MAX,
+                 uint32_t gid = UINT32_MAX) override;
+
+     protected:
         const char *
         GetCacheHostname () override;
 





More information about the lldb-commits mailing list