diff options
author | Yabin Cui <yabinc@google.com> | 2018-07-20 17:12:13 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2018-07-23 10:51:11 -0700 |
commit | 3939b9dd836c7dadeb2fe74ecef7e658d837c36d (patch) | |
tree | b5f877ece7092b02d2e6b45b4bdc714a7d392b36 /simpleperf/dso.cpp | |
parent | 3a51155fd7f7c61c333564d72fbe713feefb3674 (diff) | |
download | extras-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.cpp | 81 |
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( |