summaryrefslogtreecommitdiff
path: root/simpleperf/dso.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2018-07-20 17:12:13 -0700
committerYabin Cui <yabinc@google.com>2018-07-23 10:51:11 -0700
commit3939b9dd836c7dadeb2fe74ecef7e658d837c36d (patch)
treeb5f877ece7092b02d2e6b45b4bdc714a7d392b36 /simpleperf/dso.cpp
parent3a51155fd7f7c61c333564d72fbe713feefb3674 (diff)
downloadextras-3939b9dd836c7dadeb2fe74ecef7e658d837c36d.tar.gz
simpleperf: add --symdir option in report-sample command.
--symdir option is used to provide a directory containing files with symbols. Mutliple --symdir options can be used to provide more than one directories. For each symbol directory, simpleperf collects build id for all elf files under it recursively. Then simpleperf can use the collected build ids to find files with symbols. Also fix an error in GetCompleteProcessName(). Bug: 111687223 Test: run simpleperf_unit_test. Change-Id: Ieac5ebf7451ae85ca15c3eae37bac3c89615580b
Diffstat (limited to 'simpleperf/dso.cpp')
-rw-r--r--simpleperf/dso.cpp81
1 files changed, 56 insertions, 25 deletions
diff --git a/simpleperf/dso.cpp b/simpleperf/dso.cpp
index a9c86f4a..8e641a89 100644
--- a/simpleperf/dso.cpp
+++ b/simpleperf/dso.cpp
@@ -55,20 +55,46 @@ bool DebugElfFileFinder::SetSymFsDir(const std::string& symfs_dir) {
}
}
symfs_dir_ = dirname;
- build_id_to_file_map_.clear();
std::string build_id_list_file = symfs_dir_ + "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]] = items[1];
+ build_id_to_file_map_[items[0]] = symfs_dir_ + items[1];
}
}
}
return true;
}
+bool DebugElfFileFinder::AddSymbolDir(const std::string& symbol_dir) {
+ if (!IsDir(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();
+ }
+ CollectBuildIdInDir(dir);
+ return true;
+}
+
+void DebugElfFileFinder::CollectBuildIdInDir(const std::string& dir) {
+ for (const std::string& entry : GetEntriesInDir(dir)) {
+ std::string path = dir + "/" + entry;
+ if (IsDir(path)) {
+ CollectBuildIdInDir(path);
+ } else {
+ BuildId build_id;
+ if (GetBuildIdFromElfFile(path, &build_id) == ElfStatus::NO_ERROR) {
+ build_id_to_file_map_[build_id.ToString()] = path;
+ }
+ }
+ }
+}
+
void DebugElfFileFinder::SetVdsoFile(const std::string& vdso_file, bool is_64bit) {
if (is_64bit) {
vdso_64bit_ = vdso_file;
@@ -85,35 +111,36 @@ std::string DebugElfFileFinder::FindDebugFile(const std::string& dso_path, bool
} else if (!force_64bit && !vdso_32bit_.empty()) {
return vdso_32bit_;
}
- } else if (!symfs_dir_.empty()) {
+ }
+ // 1. Try build_id_to_file_map.
+ if (!build_id_to_file_map_.empty()) {
if (!build_id.IsEmpty() || GetBuildIdFromDsoPath(dso_path, &build_id)) {
- std::string result;
- auto check_path = [&](const std::string& path) {
- BuildId debug_build_id;
- if (GetBuildIdFromDsoPath(path, &debug_build_id) && debug_build_id == build_id) {
- result = path;
- return true;
- }
- return false;
- };
-
- // 1. Try build_id_to_file_map.
auto it = build_id_to_file_map_.find(build_id.ToString());
if (it != build_id_to_file_map_.end()) {
- if (check_path(symfs_dir_ + it->second)) {
- return result;
- }
+ return it->second;
}
- // 2. Try concatenating symfs_dir and dso_path.
- if (check_path(symfs_dir_ + dso_path)) {
- return result;
- }
- // 3. Try concatenating /usr/lib/debug and dso_path.
- // Linux host can store debug shared libraries in /usr/lib/debug.
- if (check_path("/usr/lib/debug" + dso_path)) {
- return result;
+ }
+ }
+ auto check_path = [&](const std::string& path) {
+ BuildId debug_build_id;
+ if (GetBuildIdFromDsoPath(path, &debug_build_id)) {
+ if (!build_id.IsEmpty() || GetBuildIdFromDsoPath(dso_path, &build_id)) {
+ if (build_id == debug_build_id) {
+ return true;
+ }
}
}
+ return false;
+ };
+
+ // 2. Try concatenating symfs_dir and dso_path.
+ if (!symfs_dir_.empty() && check_path(symfs_dir_ + dso_path)) {
+ return symfs_dir_ + dso_path;
+ }
+ // 3. Try concatenating /usr/lib/debug and dso_path.
+ // Linux host can store debug shared libraries in /usr/lib/debug.
+ if (check_path("/usr/lib/debug" + dso_path)) {
+ return "/usr/lib/debug" + dso_path;
}
return dso_path;
}
@@ -184,6 +211,10 @@ bool Dso::SetSymFsDir(const std::string& symfs_dir) {
return debug_elf_file_finder_.SetSymFsDir(symfs_dir);
}
+bool Dso::AddSymbolDir(const std::string& symbol_dir) {
+ return debug_elf_file_finder_.AddSymbolDir(symbol_dir);
+}
+
void Dso::SetVmlinux(const std::string& vmlinux) { vmlinux_ = vmlinux; }
void Dso::SetBuildIds(