diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2018-10-05 20:26:26 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-10-05 20:26:26 +0000 |
commit | 5fc1de62342d1b8fa638f1bda202ff51311a589f (patch) | |
tree | b3ea24759f6588ea69b789d5c9384a84c243761f | |
parent | c87973354a2be3ccc470f40e29f59df699a930b1 (diff) | |
parent | a3b752cdcf107a3c245f4e9704022dbdcfd0e678 (diff) | |
download | extras-oreo-mr1-1.2-iot-release.tar.gz |
Merge "Perfprofd: Introduce libsimpleperf_dex_read and read vdex files"android-o-mr1-iot-release-smart-display-r3oreo-mr1-1.2-iot-releasemaster-cuttlefish-testing-release
-rw-r--r-- | perfprofd/Android.bp | 22 | ||||
-rw-r--r-- | perfprofd/symbolizer.cc | 111 | ||||
-rw-r--r-- | perfprofd/tests/Android.bp | 3 | ||||
-rw-r--r-- | simpleperf/Android.bp | 31 |
4 files changed, 141 insertions, 26 deletions
diff --git a/perfprofd/Android.bp b/perfprofd/Android.bp index 61da0f50..e03508f3 100644 --- a/perfprofd/Android.bp +++ b/perfprofd/Android.bp @@ -62,14 +62,15 @@ cc_defaults { undefined: true, }, - target: { - // On the host add ASAN. - host: { - sanitize: { - address: true, - }, - }, - } +// TODO: Re-enable when ART's ASAN flags are correctly propagated. +// target: { +// // On the host add ASAN. +// host: { +// sanitize: { +// address: true, +// }, +// }, +// } } filegroup { @@ -153,6 +154,7 @@ cc_defaults { "libbase", "libperfprofd_proto_config", "libprotobuf-cpp-lite", + "libsimpleperf_dex_read", "libsimpleperf_elf_read", ], whole_static_libs: [ @@ -160,6 +162,7 @@ cc_defaults { "libperfprofd_record_proto", "libquipper", ], + shared_libs: ["libart"], srcs: [ "perf_data_converter.cc", "configreader.cc", @@ -213,6 +216,7 @@ cc_binary { name: "perfprofd", defaults: [ "perfprofd_defaults", + "libsimpleperf_dex_read_static_reqs_defaults", "libsimpleperf_elf_read_static_reqs_defaults", ], @@ -225,12 +229,14 @@ cc_binary { "libperfprofdcore", "libperfprofd_binder", "libperfprofd_proto_config", + "libsimpleperf_dex_read", "libsimpleperf_elf_read", ], group_static_libs: true, shared_libs: [ "android.hardware.health@2.0", + "libart", "liblog", "libprotobuf-cpp-lite", "libbase", diff --git a/perfprofd/symbolizer.cc b/perfprofd/symbolizer.cc index bde680f5..58ff280b 100644 --- a/perfprofd/symbolizer.cc +++ b/perfprofd/symbolizer.cc @@ -22,9 +22,11 @@ #include <unordered_map> #include <android-base/logging.h> - -#include "build_id.h" -#include "read_elf.h" +#include <base/mem_map.h> +#include <build_id.h> +#include <read_dex_file.h> +#include <read_elf.h> +#include <vdex_file.h> namespace perfprofd { @@ -33,6 +35,8 @@ namespace { struct SimpleperfSymbolizer : public Symbolizer { // For simplicity, we assume non-overlapping symbols. struct Symbol { + Symbol(const std::string& n, uint64_t l) : name(n), length(l) {} + std::string name; uint64_t length; }; @@ -66,28 +70,99 @@ struct SimpleperfSymbolizer : public Symbolizer { } void LoadDso(const std::string& dso) { - SymbolMap data; - auto callback = [&data](const ElfFileSymbol& sym) { - if (sym.is_func) { - Symbol symbol; - symbol.name = sym.name; - symbol.length = sym.len; - if (sym.len == 0) { - LOG(ERROR) << "Symbol size is zero for " << sym.name; + // See whether it's an ELF file. + { + SymbolMap elf_data; + auto callback = [&elf_data](const ElfFileSymbol& sym) { + if (sym.is_func) { + if (sym.len == 0) { + LOG(ERROR) << "Symbol size is zero for " << sym.name; + } + elf_data.emplace(sym.vaddr, Symbol(sym.name, sym.len)); } - data.emplace(sym.vaddr, std::move(symbol)); + }; + ElfStatus status = ParseSymbolsFromElfFile(dso, BuildId(), callback); + if (status == ElfStatus::NO_ERROR) { + dsos.emplace(dso, std::move(elf_data)); + return; + } + } + + // See whether it's a vdex file. + { + ::art::MemMap::Init(); + + using VdexFile = ::art::VdexFile; + std::string error_msg; + std::unique_ptr<VdexFile> vdex = VdexFile::Open(dso, + /* writable= */ false, + /* low_4gb= */ false, + /* unquicken= */ false, + &error_msg); + if (vdex != nullptr) { + const uint8_t* cur = nullptr; + std::vector<uint64_t> dex_file_offsets; + const uint8_t* base = vdex->Begin(); + for (;;) { + cur = vdex->GetNextDexFileData(cur); + if (cur == nullptr) { + break; + } + dex_file_offsets.push_back(cur - base); + } + + if (!dex_file_offsets.empty()) { + std::vector<DexFileSymbol> symbols; + if (ReadSymbolsFromDexFile(dso, dex_file_offsets, &symbols)) { + SymbolMap vdex_data; + for (const DexFileSymbol& symbol : symbols) { + vdex_data.emplace(symbol.offset, Symbol(symbol.name, symbol.len)); + } + dsos.emplace(dso, std::move(vdex_data)); + LOG(INFO) << "Found " << symbols.size() << " dex symbols in " << dso; + return; + } else { + LOG(WARNING) << "Could not read symbols from dex files in " << dso; + } + } else { + LOG(WARNING) << "Could not find dex files for vdex " << dso; + dsos.emplace(dso, SymbolMap()); + } + } else { + LOG(WARNING) << dso << " is not a vdex: " << error_msg; } - }; - ElfStatus status = ParseSymbolsFromElfFile(dso, BuildId(), callback); - if (status != ElfStatus::NO_ERROR) { - LOG(WARNING) << "Could not parse dso " << dso << ": " << status; } - dsos.emplace(dso, std::move(data)); + + // TODO: See whether it's a dex file. + + // OK, give up. + LOG(WARNING) << "Could not symbolize " << dso; + dsos.emplace(dso, SymbolMap()); } bool GetMinExecutableVAddr(const std::string& dso, uint64_t* addr) override { ElfStatus status = ReadMinExecutableVirtualAddressFromElfFile(dso, BuildId(), addr); - return status == ElfStatus::NO_ERROR; + if (status != ElfStatus::NO_ERROR) { + return true; + } + + { + ::art::MemMap::Init(); + + using VdexFile = ::art::VdexFile; + std::string error_msg; + std::unique_ptr<VdexFile> vdex = VdexFile::Open(dso, + /* writable= */ false, + /* low_4gb= */ false, + /* unquicken= */ false, + &error_msg); + if (vdex != nullptr) { + *addr = 0u; + return true; + } + } + + return false; } std::unordered_map<std::string, SymbolMap> dsos; diff --git a/perfprofd/tests/Android.bp b/perfprofd/tests/Android.bp index 215f9fc3..837c28fb 100644 --- a/perfprofd/tests/Android.bp +++ b/perfprofd/tests/Android.bp @@ -19,6 +19,7 @@ cc_test { name: "perfprofd_test", defaults: [ "perfprofd_test_defaults", + "libsimpleperf_dex_read_static_reqs_defaults", "libsimpleperf_elf_read_static_reqs_defaults", ], test_suites: ["device-tests"], @@ -28,6 +29,7 @@ cc_test { static_libs: [ "libperfprofdcored", "libperfprofd_proto_config", + "libsimpleperf_dex_read", "libsimpleperf_elf_read", "libbase", "libutils", @@ -35,6 +37,7 @@ cc_test { "libprotobuf-cpp-lite", "liblog", ], + shared_libs: ["libart"], target: { host: { host_ldlibs: [ diff --git a/simpleperf/Android.bp b/simpleperf/Android.bp index dc98a269..759aee54 100644 --- a/simpleperf/Android.bp +++ b/simpleperf/Android.bp @@ -94,3 +94,34 @@ cc_library_static { group_static_libs: true, } + +cc_defaults { + name: "libsimpleperf_dex_read_static_reqs_defaults", + defaults: ["libdexfile_static_defaults"], +} + +cc_library_static { + name: "libsimpleperf_dex_read", + defaults: [ + "simpleperf_defaults", + "libsimpleperf_dex_read_static_reqs_defaults", + ], + host_supported: true, + + export_include_dirs: [ + ".", + ], + + // TODO: fix or workaround this. + cflags: [ + "-DSIMPLEPERF_REVISION=\"dummy\"", + ], + + static_libs: ["libbase"], + + srcs: [ + "read_dex_file.cpp", + ], + + group_static_libs: true, +} |