summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2018-10-05 20:26:26 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-10-05 20:26:26 +0000
commit5fc1de62342d1b8fa638f1bda202ff51311a589f (patch)
treeb3ea24759f6588ea69b789d5c9384a84c243761f
parentc87973354a2be3ccc470f40e29f59df699a930b1 (diff)
parenta3b752cdcf107a3c245f4e9704022dbdcfd0e678 (diff)
downloadextras-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.bp22
-rw-r--r--perfprofd/symbolizer.cc111
-rw-r--r--perfprofd/tests/Android.bp3
-rw-r--r--simpleperf/Android.bp31
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,
+}