diff options
author | Yabin Cui <yabinc@google.com> | 2018-10-29 14:23:48 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2018-10-30 15:48:22 -0700 |
commit | 1b9b1c1c112f79b47b050d1975fbb08b566356f7 (patch) | |
tree | 7e3571bae1b288a5a87cb1fc665e9cd7e6fde118 /simpleperf/dso.cpp | |
parent | b27fec0d91b6a33776e831f2c898ab5a71e07340 (diff) | |
download | extras-1b9b1c1c112f79b47b050d1975fbb08b566356f7.tar.gz |
simpleperf: fix simpleperf_unit_test on windows.
Fix test failures caused by path separator and newline character.
Bug: 117568547
Test: run simpleperf_unit_test on windows.
Change-Id: I0522268368a2288893ecd52f505382c512d1d7c9
Diffstat (limited to 'simpleperf/dso.cpp')
-rw-r--r-- | simpleperf/dso.cpp | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/simpleperf/dso.cpp b/simpleperf/dso.cpp index 50a3dc84..d2c674b0 100644 --- a/simpleperf/dso.cpp +++ b/simpleperf/dso.cpp @@ -36,6 +36,14 @@ namespace simpleperf_dso_impl { +std::string RemovePathSeparatorSuffix(const std::string& path) { + // Don't remove path separator suffix for '/'. + if (android::base::EndsWith(path, OS_PATH_SEPARATOR) && path.size() > 1u) { + return path.substr(0, path.size() - 1); + } + return path; +} + void DebugElfFileFinder::Reset() { vdso_64bit_.clear(); vdso_32bit_.clear(); @@ -44,24 +52,18 @@ void DebugElfFileFinder::Reset() { } bool DebugElfFileFinder::SetSymFsDir(const std::string& symfs_dir) { - std::string dirname = symfs_dir; - if (!dirname.empty()) { - if (dirname.back() != '/') { - dirname.push_back('/'); - } - if (!IsDir(symfs_dir)) { - LOG(ERROR) << "Invalid symfs_dir '" << symfs_dir << "'"; - return false; - } + symfs_dir_ = RemovePathSeparatorSuffix(symfs_dir); + if (!IsDir(symfs_dir_)) { + LOG(ERROR) << "Invalid symfs_dir '" << symfs_dir_ << "'"; + return false; } - symfs_dir_ = dirname; - std::string build_id_list_file = symfs_dir_ + "build_id_list"; + std::string build_id_list_file = symfs_dir_ + OS_PATH_SEPARATOR + "build_id_list"; std::string build_id_list; if (android::base::ReadFileToString(build_id_list_file, &build_id_list)) { for (auto& line : android::base::Split(build_id_list, "\n")) { std::vector<std::string> items = android::base::Split(line, "="); if (items.size() == 2u) { - build_id_to_file_map_[items[0]] = symfs_dir_ + items[1]; + build_id_to_file_map_[items[0]] = symfs_dir_ + OS_PATH_SEPARATOR + items[1]; } } } @@ -73,17 +75,14 @@ bool DebugElfFileFinder::AddSymbolDir(const std::string& symbol_dir) { LOG(ERROR) << "Invalid symbol dir " << symbol_dir; return false; } - std::string dir = symbol_dir; - if (dir.size() > 1 && dir.back() == '/') { - dir.pop_back(); - } + std::string dir = RemovePathSeparatorSuffix(symbol_dir); CollectBuildIdInDir(dir); return true; } void DebugElfFileFinder::CollectBuildIdInDir(const std::string& dir) { for (const std::string& entry : GetEntriesInDir(dir)) { - std::string path = dir + "/" + entry; + std::string path = dir + OS_PATH_SEPARATOR + entry; if (IsDir(path)) { CollectBuildIdInDir(path); } else { @@ -134,8 +133,11 @@ std::string DebugElfFileFinder::FindDebugFile(const std::string& dso_path, bool }; // 2. Try concatenating symfs_dir and dso_path. - if (!symfs_dir_.empty() && check_path(symfs_dir_ + dso_path)) { - return symfs_dir_ + dso_path; + if (!symfs_dir_.empty()) { + std::string path = GetPathInSymFsDir(dso_path); + if (check_path(path)) { + return path; + } } // 3. Try concatenating /usr/lib/debug and dso_path. // Linux host can store debug shared libraries in /usr/lib/debug. @@ -144,6 +146,30 @@ std::string DebugElfFileFinder::FindDebugFile(const std::string& dso_path, bool } return dso_path; } + +std::string DebugElfFileFinder::GetPathInSymFsDir(const std::string& path) { + auto add_symfs_prefix = [&](const std::string& path) { + if (android::base::StartsWith(path, OS_PATH_SEPARATOR)) { + return symfs_dir_ + path; + } + return symfs_dir_ + OS_PATH_SEPARATOR + path; + }; + if (OS_PATH_SEPARATOR == '/') { + return add_symfs_prefix(path); + } + // Paths in recorded perf.data uses '/' as path separator. When reporting on Windows, it needs + // to be converted to '\\'. + auto tuple = SplitUrlInApk(path); + if (std::get<0>(tuple)) { + std::string apk_path = std::get<1>(tuple); + std::string entry_path = std::get<2>(tuple); + std::replace(apk_path.begin(), apk_path.end(), '/', OS_PATH_SEPARATOR); + return GetUrlInApk(add_symfs_prefix(apk_path), entry_path); + } + std::string elf_path = path; + std::replace(elf_path.begin(), elf_path.end(), '/', OS_PATH_SEPARATOR); + return add_symfs_prefix(elf_path); +} } // namespace simpleperf_dso_imp static OneTimeFreeAllocator symbol_name_allocator; |