summaryrefslogtreecommitdiff
path: root/simpleperf/dso.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2018-10-29 14:23:48 -0700
committerYabin Cui <yabinc@google.com>2018-10-30 15:48:22 -0700
commit1b9b1c1c112f79b47b050d1975fbb08b566356f7 (patch)
tree7e3571bae1b288a5a87cb1fc665e9cd7e6fde118 /simpleperf/dso.cpp
parentb27fec0d91b6a33776e831f2c898ab5a71e07340 (diff)
downloadextras-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.cpp64
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;