tberghammer created this revision. tberghammer added a reviewer: ovyalov. tberghammer added a subscriber: lldb-commits. Herald added subscribers: danalbert, tberghammer.
Change oat symbolization code for android to work on non-rooted devices On android when debugging an apk we run lldb-server as application user because the sell user (on non-rooted device) can't attach to an application. The problem is that "adb pull" will run as a shell user what can't access to files created by lldb-server because they will be owned by the application user. This CL changes the oat symbolization code to run "oatdump --symbolize" to generate an output what is owned by the shell user. http://reviews.llvm.org/D13162 Files: source/Plugins/Platform/Android/AdbClient.cpp source/Plugins/Platform/Android/AdbClient.h source/Plugins/Platform/Android/PlatformAndroid.cpp
Index: source/Plugins/Platform/Android/PlatformAndroid.cpp =================================================================== --- source/Plugins/Platform/Android/PlatformAndroid.cpp +++ source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -325,33 +325,23 @@ if (module_sp->GetSectionList()->FindSectionByName(ConstString(".symtab")) != nullptr) return Error("Symtab already available in the module"); - int status = 0; - std::string tmpdir; - StreamString command; - command.Printf("mktemp --directory --tmpdir %s", GetWorkingDirectory().GetCString()); - Error error = RunShellCommand(command.GetData(), - GetWorkingDirectory(), - &status, - nullptr, - &tmpdir, - 5 /* timeout (s) */); + AdbClient adb(m_device_id); - if (error.Fail() || status != 0 || tmpdir.empty()) + std::string tmpdir; + Error error = adb.Shell("mktemp --directory --tmpdir /data/local/tmp", 5000 /* ms */, &tmpdir); + if (error.Fail() || tmpdir.empty()) return Error("Failed to generate temporary directory on the device (%s)", error.AsCString()); tmpdir.erase(tmpdir.size() - 1); // Remove trailing new line // Create file remover for the temporary directory created on the device std::unique_ptr<std::string, std::function<void(std::string*)>> tmpdir_remover( &tmpdir, [this](std::string* s) { + AdbClient adb(m_device_id); + StreamString command; command.Printf("rm -rf %s", s->c_str()); - Error error = this->RunShellCommand(command.GetData(), - GetWorkingDirectory(), - nullptr, - nullptr, - nullptr, - 5 /* timeout (s) */); + Error error = adb.Shell(command.GetData(), 5000 /* ms */, nullptr); Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); if (error.Fail()) @@ -363,17 +353,13 @@ symfile_platform_filespec.AppendPathComponent("symbolized.oat"); // Execute oatdump on the remote device to generate a file with symtab - command.Clear(); + StreamString command; command.Printf("oatdump --symbolize=%s --output=%s", module_sp->GetPlatformFileSpec().GetCString(false), symfile_platform_filespec.GetCString(false)); - error = RunShellCommand(command.GetData(), - GetWorkingDirectory(), - &status, - nullptr, - nullptr, - 60 /* timeout (s) */); - if (error.Fail() || status != 0) + std::string output; + error = adb.Shell(command.GetData(), 60000 /* ms */, &output); + if (error.Fail()) return Error("Oatdump failed: %s", error.AsCString()); // Download the symbolfile from the remote device Index: source/Plugins/Platform/Android/AdbClient.h =================================================================== --- source/Plugins/Platform/Android/AdbClient.h +++ source/Plugins/Platform/Android/AdbClient.h @@ -62,6 +62,9 @@ Error Stat (const FileSpec &remote_file, uint32_t &mode, uint32_t &size, uint32_t &mtime); + Error + Shell (const char* command, uint32_t timeout_ms, std::string* output); + private: Error Connect (); @@ -85,6 +88,9 @@ ReadMessage (std::vector<char> &message); Error + ReadMessageStream (std::vector<char> &message, uint32_t timeout_ms); + + Error GetResponseError (const char *response_id); Error Index: source/Plugins/Platform/Android/AdbClient.cpp =================================================================== --- source/Plugins/Platform/Android/AdbClient.cpp +++ source/Plugins/Platform/Android/AdbClient.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataEncoder.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/StreamString.h" #include "lldb/Host/FileSpec.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -212,6 +213,28 @@ } Error +AdbClient::ReadMessageStream (std::vector<char>& message, uint32_t timeout_ms) +{ + auto start = std::chrono::steady_clock::now(); + message.clear(); + + Error error; + lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; + char buffer[1024]; + while (error.Success() && status == lldb::eConnectionStatusSuccess) + { + auto end = std::chrono::steady_clock::now(); + uint32_t elapsed_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); + if (elapsed_time >= timeout_ms) + return Error("Timed out"); + + size_t n = m_conn.Read(buffer, sizeof(buffer), 1000 * (timeout_ms - elapsed_time), status, &error); + message.insert(message.end(), &buffer[0], &buffer[n]); + } + return error; +} + +Error AdbClient::ReadResponseStatus() { char response_id[5]; @@ -493,3 +516,30 @@ mtime = extractor.GetU32 (&offset); return Error (); } + +Error +AdbClient::Shell (const char* command, uint32_t timeout_ms, std::string* output) +{ + auto error = SwitchDeviceTransport (); + if (error.Fail ()) + return Error ("Failed to switch to device transport: %s", error.AsCString ()); + + StreamString adb_command; + adb_command.Printf("shell:%s", command); + error = SendMessage (adb_command.GetData(), false); + if (error.Fail ()) + return error; + + error = ReadResponseStatus (); + if (error.Fail ()) + return error; + + std::vector<char> in_buffer; + error = ReadMessageStream (in_buffer, timeout_ms); + if (error.Fail()) + return error; + + if (output) + output->assign(in_buffer.begin(), in_buffer.end()); + return error; +}
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits