From 17769f2253355fefa6ebad17674113d695ecc91b Mon Sep 17 00:00:00 2001 From: Yabin Cui Date: Tue, 13 Jul 2021 16:39:16 -0700 Subject: simpleperf: improve debugging reading dex file. Print debug_filename in ReadSymbolsFromDexFileInMemory() when failed to read symbols. Simplify the code by removing open_file_cb. Bug: none Test: run simpleperF_unit_test Change-Id: Ie776f3993898be5245e612bf599fa229dc650944 --- simpleperf/dso.cpp | 8 +-- simpleperf/nonlinux_support/nonlinux_support.cpp | 3 +- simpleperf/read_dex_file.cpp | 71 +++++++++++------------- simpleperf/read_dex_file.h | 2 +- 4 files changed, 38 insertions(+), 46 deletions(-) diff --git a/simpleperf/dso.cpp b/simpleperf/dso.cpp index 73e21ef8..8d002388 100644 --- a/simpleperf/dso.cpp +++ b/simpleperf/dso.cpp @@ -478,8 +478,8 @@ class DexFileDso : public Dso { std::vector data; if (ahelper && ahelper->FindEntry(std::get<2>(tuple), &entry) && ahelper->GetEntryData(entry, &data)) { - status = ReadSymbolsFromDexFileInMemory(data.data(), data.size(), dex_file_offsets_, - symbol_callback); + status = ReadSymbolsFromDexFileInMemory(data.data(), data.size(), debug_file_path_, + dex_file_offsets_, symbol_callback); } } else { status = ReadSymbolsFromDexFile(debug_file_path_, dex_file_offsets_, symbol_callback); @@ -487,10 +487,10 @@ class DexFileDso : public Dso { if (!status) { android::base::LogSeverity level = symbols_.empty() ? android::base::WARNING : android::base::DEBUG; - LOG(level) << "Failed to read symbols from " << debug_file_path_; + LOG(level) << "Failed to read symbols from dex_file " << debug_file_path_; return symbols; } - LOG(VERBOSE) << "Read symbols from " << debug_file_path_ << " successfully"; + LOG(VERBOSE) << "Read symbols from dex_file " << debug_file_path_ << " successfully"; SortAndFixSymbols(symbols); return symbols; } diff --git a/simpleperf/nonlinux_support/nonlinux_support.cpp b/simpleperf/nonlinux_support/nonlinux_support.cpp index 2268e301..8ef2b9b3 100644 --- a/simpleperf/nonlinux_support/nonlinux_support.cpp +++ b/simpleperf/nonlinux_support/nonlinux_support.cpp @@ -31,7 +31,8 @@ bool CanRecordRawData() { return false; } -bool ReadSymbolsFromDexFileInMemory(void*, uint64_t, const std::vector&, +bool ReadSymbolsFromDexFileInMemory(void*, uint64_t, const std::string&, + const std::vector&, const std::function&) { return true; } diff --git a/simpleperf/read_dex_file.cpp b/simpleperf/read_dex_file.cpp index 13ca403f..afab576b 100644 --- a/simpleperf/read_dex_file.cpp +++ b/simpleperf/read_dex_file.cpp @@ -33,52 +33,42 @@ namespace simpleperf { -static bool ReadSymbols( - const std::vector& dex_file_offsets, - const std::function(uint64_t offset)>& open_file_cb, - const std::function& symbol_cb) { - for (uint64_t dex_offset : dex_file_offsets) { - std::unique_ptr dex_file = open_file_cb(dex_offset); +static void ReadSymbols(art_api::dex::DexFile& dex_file, uint64_t file_offset, + const std::function& symbol_cb) { + auto callback = [&](const art_api::dex::DexFile::Method& method) { + size_t name_size, code_size; + const char* name = method.GetQualifiedName(/*with_params=*/false, &name_size); + size_t offset = method.GetCodeOffset(&code_size); + DexFileSymbol symbol{std::string_view(name, name_size), file_offset + offset, code_size}; + symbol_cb(&symbol); + }; + dex_file.ForEachMethod(callback); +} + +bool ReadSymbolsFromDexFileInMemory(void* addr, uint64_t size, const std::string& debug_filename, + const std::vector& dex_file_offsets, + const std::function& symbol_callback) { + for (uint64_t file_offset : dex_file_offsets) { + size_t max_file_size; + if (__builtin_sub_overflow(size, file_offset, &max_file_size)) { + LOG(WARNING) << "failed to read dex file symbols from " << debug_filename << "(offset " + << file_offset << ")"; + return false; + } + uint8_t* file_addr = static_cast(addr) + file_offset; + std::unique_ptr dex_file; + art_api::dex::DexFile::Error error_msg = + art_api::dex::DexFile::Create(file_addr, max_file_size, nullptr, "", &dex_file); if (dex_file == nullptr) { + LOG(WARNING) << "failed to read dex file symbols from " << debug_filename << "(offset " + << file_offset << "): " << error_msg.ToString(); return false; } - - auto callback = [&](const art_api::dex::DexFile::Method& method) { - size_t name_size, code_size; - const char* name = method.GetQualifiedName(/*with_params=*/false, &name_size); - size_t offset = method.GetCodeOffset(&code_size); - DexFileSymbol symbol{std::string_view(name, name_size), dex_offset + offset, code_size}; - symbol_cb(&symbol); - }; - dex_file->ForEachMethod(callback); + ReadSymbols(*dex_file, file_offset, symbol_callback); } - return true; } -bool ReadSymbolsFromDexFileInMemory(void* addr, uint64_t size, - const std::vector& dex_file_offsets, - const std::function& symbol_callback) { - return ReadSymbols( - dex_file_offsets, - [&](uint64_t offset) -> std::unique_ptr { - size_t max_file_size; - if (__builtin_sub_overflow(size, offset, &max_file_size)) { - return nullptr; - } - uint8_t* file_addr = static_cast(addr) + offset; - std::unique_ptr dex_file; - art_api::dex::DexFile::Error error_msg = - art_api::dex::DexFile::Create(file_addr, max_file_size, nullptr, "", &dex_file); - if (dex_file == nullptr) { - LOG(WARNING) << "Failed to read dex file symbols: " << error_msg.ToString(); - return nullptr; - } - return dex_file; - }, - symbol_callback); -} - bool ReadSymbolsFromDexFile(const std::string& file_path, const std::vector& dex_file_offsets, const std::function& symbol_callback) { @@ -95,7 +85,8 @@ bool ReadSymbolsFromDexFile(const std::string& file_path, if (map == nullptr) { return false; } - return ReadSymbolsFromDexFileInMemory(map->data(), file_size, dex_file_offsets, symbol_callback); + return ReadSymbolsFromDexFileInMemory(map->data(), file_size, file_path, dex_file_offsets, + symbol_callback); } } // namespace simpleperf diff --git a/simpleperf/read_dex_file.h b/simpleperf/read_dex_file.h index b4298fab..7700a06a 100644 --- a/simpleperf/read_dex_file.h +++ b/simpleperf/read_dex_file.h @@ -34,7 +34,7 @@ struct DexFileSymbol { uint64_t size; }; -bool ReadSymbolsFromDexFileInMemory(void* addr, uint64_t size, +bool ReadSymbolsFromDexFileInMemory(void* addr, uint64_t size, const std::string& debug_filename, const std::vector& dex_file_offsets, const std::function& symbol_callback); bool ReadSymbolsFromDexFile(const std::string& file_path, -- cgit v1.2.3