[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