summaryrefslogtreecommitdiff
path: root/simpleperf/dso.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2020-07-17 16:12:15 -0700
committerYabin Cui <yabinc@google.com>2020-07-17 16:49:07 -0700
commit991477b01f7d72bcd03b9e6d4f706687d912e7e6 (patch)
tree228bfddfa0adf2cf8eef82816328cefb5eb3fb9f /simpleperf/dso.cpp
parentf67298aa2b500a7959318d2ece2e67064d60e430 (diff)
downloadextras-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.cpp48
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: