diff options
author | Yabin Cui <yabinc@google.com> | 2020-07-17 16:12:15 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2020-07-17 16:49:07 -0700 |
commit | 991477b01f7d72bcd03b9e6d4f706687d912e7e6 (patch) | |
tree | 228bfddfa0adf2cf8eef82816328cefb5eb3fb9f /simpleperf/dso.cpp | |
parent | f67298aa2b500a7959318d2ece2e67064d60e430 (diff) | |
download | extras-991477b01f7d72bcd03b9e6d4f706687d912e7e6.tar.gz |
simpleperf: find debug files for kernel modules.
Also print a warning when a debug file in symfs_dir can't be used
because of build_id mismatch.
Bug: 161546498
Test: run simpleperf_unit_test
Change-Id: I8d1d538a4a62339d236e665141b114428776fb54
Diffstat (limited to 'simpleperf/dso.cpp')
-rw-r--r-- | simpleperf/dso.cpp | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/simpleperf/dso.cpp b/simpleperf/dso.cpp index 975a391a..df07393f 100644 --- a/simpleperf/dso.cpp +++ b/simpleperf/dso.cpp @@ -106,6 +106,29 @@ void DebugElfFileFinder::SetVdsoFile(const std::string& vdso_file, bool is_64bit } } +static bool CheckDebugFilePath(const std::string& path, BuildId& build_id, + bool report_build_id_mismatch) { + ElfStatus status; + auto elf = ElfFile::Open(path, &status); + if (!elf) { + return false; + } + BuildId debug_build_id; + status = elf->GetBuildId(&debug_build_id); + if (status != ElfStatus::NO_ERROR && status != ElfStatus::NO_BUILD_ID) { + return false; + } + + // Native libraries in apks and kernel modules may not have build ids. + // So build_id and debug_build_id can either be empty, or have the same value. + bool match = build_id == debug_build_id; + if (!match && report_build_id_mismatch) { + LOG(WARNING) << path << " isn't used because of build id mismatch: expected " << build_id + << ", real " << debug_build_id; + } + return match; +} + std::string DebugElfFileFinder::FindDebugFile(const std::string& dso_path, bool force_64bit, BuildId& build_id) { if (dso_path == "[vdso]") { @@ -119,22 +142,12 @@ std::string DebugElfFileFinder::FindDebugFile(const std::string& dso_path, bool // Try reading build id from file if we don't already have one. GetBuildIdFromDsoPath(dso_path, &build_id); } - auto check_path = [&](const std::string& path) { - BuildId debug_build_id; - GetBuildIdFromDsoPath(path, &debug_build_id); - if (build_id.IsEmpty()) { - // Native libraries in apks may not have build ids. When looking for a debug elf file without - // build id (build id is empty), the debug file should exist and also not have build id. - return IsRegularFile(path) && debug_build_id.IsEmpty(); - } - return build_id == debug_build_id; - }; // 1. Try build_id_to_file_map. if (!build_id_to_file_map_.empty()) { if (!build_id.IsEmpty() || GetBuildIdFromDsoPath(dso_path, &build_id)) { auto it = build_id_to_file_map_.find(build_id.ToString()); - if (it != build_id_to_file_map_.end() && check_path(it->second)) { + if (it != build_id_to_file_map_.end() && CheckDebugFilePath(it->second, build_id, false)) { return it->second; } } @@ -142,18 +155,18 @@ std::string DebugElfFileFinder::FindDebugFile(const std::string& dso_path, bool if (!symfs_dir_.empty()) { // 2. Try concatenating symfs_dir and dso_path. std::string path = GetPathInSymFsDir(dso_path); - if (check_path(path)) { + if (CheckDebugFilePath(path, build_id, true)) { return path; } // 3. Try concatenating symfs_dir and basename of dso_path. path = symfs_dir_ + OS_PATH_SEPARATOR + android::base::Basename(dso_path); - if (check_path(path)) { + if (CheckDebugFilePath(path, build_id, false)) { return path; } } // 4. 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)) { + if (CheckDebugFilePath("/usr/lib/debug" + dso_path, build_id, false)) { return "/usr/lib/debug" + dso_path; } return dso_path; @@ -688,8 +701,11 @@ std::unique_ptr<Dso> Dso::CreateDso(DsoType dso_type, const std::string& dso_pat } case DSO_KERNEL: return std::unique_ptr<Dso>(new KernelDso(dso_path, dso_path)); - case DSO_KERNEL_MODULE: - return std::unique_ptr<Dso>(new KernelModuleDso(dso_path, dso_path)); + case DSO_KERNEL_MODULE: { + BuildId build_id = FindExpectedBuildIdForPath(dso_path); + return std::unique_ptr<Dso>(new KernelModuleDso( + dso_path, debug_elf_file_finder_.FindDebugFile(dso_path, force_64bit, build_id))); + } case DSO_DEX_FILE: return std::unique_ptr<Dso>(new DexFileDso(dso_path, dso_path)); case DSO_UNKNOWN_FILE: |