From ef3fc54474636f5c9d050443d794dc7f70033a68 Mon Sep 17 00:00:00 2001 From: hongbinj Date: Fri, 10 Feb 2023 19:13:12 +0800 Subject: [PATCH] [LLDB] Fix loading modules outside container first that causes the failure of stack unwinding and step-in command With platform being "remote-hos inner", lldb may fail to resolve modules properly because at first lldb tries to get shared libraries residing outside the container. If a library with the same path but different content is pulled, DWARF-based unwinding fails, and it falls back into the unreliable frame-pointer-based unwinding (it is not dependable because the frame pointer resiter may be used as a general purpose register with the compiler flag -fomit-frame-pointer). The issue can be fixed by retrieving shared libraries inside the container instead. Issue: I6EC7I Test: build lldb and debug on devices Signed-off-by: hongbinj --- .../Plugins/Platform/HOS/PlatformHOS.cpp | 105 +++++++++++------- .../source/Plugins/Platform/HOS/PlatformHOS.h | 5 + 2 files changed, 67 insertions(+), 43 deletions(-) diff --git a/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp b/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp index d69bef24f212..c279f9368210 100644 --- a/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp +++ b/lldb/source/Plugins/Platform/HOS/PlatformHOS.cpp @@ -34,6 +34,14 @@ static uint32_t g_initialize_count = 0; static const unsigned int g_hos_default_cache_size = 2048; LLDB_PLUGIN_DEFINE(PlatformHOS) +using PrefixMap = std::pair; + +static constexpr std::array PATH_PREFIX_MAP {{ + { "/data", "/data/ohos_data" }, + { "/vendor", "/vendor/ohos/vendor" }, + { "/system", "/system/ohos/system" }, +}}; + static void platform_setenv(const char *env, const char *val) { #if HAVE_SETENV || _MSC_VER setenv(env, val, true); @@ -218,20 +226,69 @@ Status PlatformHOS::GetFile(const FileSpec &source, source_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent( source_spec.GetCString(false)); + if (GetContainer()) { + return GetFileFromContainer(source_spec, destination); + } + + return DoGetFile(source_spec, destination); +} + +// Precondition: source and destination represent POSIX-style +// and aboslute paths. +Status PlatformHOS::GetFileFromContainer(const FileSpec &source, + const FileSpec &destination) { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM); + llvm::StringRef path(source.GetCString(false)); + + for (const auto& map : PATH_PREFIX_MAP) { + const auto& prefix = map.first; + const auto& new_prefix = map.second; + + if (path.startswith(prefix)) { + FileSpec new_source(new_prefix, FileSpec::Style::posix); + new_source.AppendPathComponent(path.substr(prefix.size())); + + LLDB_LOGF(log, "path '%s' inside container is converted to '%s'", + source.GetCString(false), new_source.GetCString(false)); + + Status error = DoGetFile(new_source, destination); + + if (error.Fail()) { + LLDB_LOGF(log, "failed to get file '%s': %s", + new_source.GetCString(false), error.AsCString()); + LLDB_LOGF(log, "try to get file '%s' as a fallback", + source.GetCString(false)); + error = DoGetFile(source, destination); + } + + return error; + } + } + + LLDB_LOGF(log, "try to get file '%s' inside container without conversion", + source.GetCString(false)); + + return DoGetFile(source, destination); +} + +// Precondition: source and destination represent POSIX-style +// and aboslute paths. +Status PlatformHOS::DoGetFile(const FileSpec &source, + const FileSpec &destination) { Status error; auto sync_service = GetSyncService(error); if (error.Fail()) return error; uint32_t mode = 0, size = 0, mtime = 0; - error = sync_service->Stat(source_spec, mode, size, mtime); + error = sync_service->Stat(source, mode, size, mtime); if (error.Fail()) return error; if (mode != 0) - return sync_service->PullFile(source_spec, destination); + return sync_service->PullFile(source, destination); - auto source_file = source_spec.GetCString(false); + const auto *source_file = source.GetCString(false); Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); LLDB_LOGF(log, "Got mode == 0 on '%s': try to get file via 'shell cat'", @@ -242,54 +299,16 @@ Status PlatformHOS::GetFile(const FileSpec &source, // mode == 0 can signify that adbd cannot access the file due security // constraints - try "cat ..." as a fallback. - if (log) { - LLDB_LOGF(log, "Hsu file(%s):%d PlatformHOS::%s source_file(%s)", __FILE__, - __LINE__, __FUNCTION__, source_file); - } HdcClient hdc(m_device_id); char cmd[PATH_MAX]; - int len = strlen(source_file); - std::string tempFile(source_file); - if (m_container) { - /* - /data /data/ohos_data - /vendor /sytem/ohos/vendor - /system /system/ohos/system - */ - const std::string str_data = "/data"; - const std::string str_vendor = "/vendor"; - const std::string str_system = "/system"; - const std::string str_data_append = "/data/ohos_data"; - const std::string str_vendor_append = "/vendor/ohos/vendor"; - const std::string str_system_append = "/system/ohos/system"; - if (!strncmp(source_file, str_data.c_str(), strlen(str_data.c_str()))) { - tempFile = str_data_append + tempFile.substr(strlen(str_data.c_str())); - snprintf(cmd, sizeof(cmd), "cat '%s'", tempFile.c_str()); - return hdc.ShellToFile(cmd, minutes(1), destination); - } - if (!strncmp(source_file, str_vendor.c_str(), strlen(str_vendor.c_str()))) { - tempFile = - str_vendor_append + tempFile.substr(strlen(str_vendor.c_str())); - snprintf(cmd, sizeof(cmd), "cat '%s'", tempFile.c_str()); - return hdc.ShellToFile(cmd, minutes(1), destination); - } - - if (!strncmp(source_file, str_system.c_str(), strlen(str_system.c_str()))) { - tempFile = - str_system_append + tempFile.substr(strlen(str_system.c_str())); - snprintf(cmd, sizeof(cmd), "cat '%s'", tempFile.c_str()); - return hdc.ShellToFile(cmd, minutes(1), destination); - } - return error; - } else { - snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); - } + snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); if (log) { LLDB_LOGF(log, "Hsu file(%s):%d PlatformHOS::%s source_file(%s)", __FILE__, __LINE__, __FUNCTION__, source_file); } + return hdc.ShellToFile(cmd, minutes(1), destination); } diff --git a/lldb/source/Plugins/Platform/HOS/PlatformHOS.h b/lldb/source/Plugins/Platform/HOS/PlatformHOS.h index 40e291a2d35f..d7ce912e6166 100644 --- a/lldb/source/Plugins/Platform/HOS/PlatformHOS.h +++ b/lldb/source/Plugins/Platform/HOS/PlatformHOS.h @@ -71,6 +71,11 @@ protected: private: std::unique_ptr GetSyncService(Status &error); + Status GetFileFromContainer(const FileSpec &source, + const FileSpec &destination); + + Status DoGetFile(const FileSpec &source, const FileSpec &destination); + std::string m_device_id; uint32_t m_sdk_version; }; -- Gitee