summaryrefslogtreecommitdiff
path: root/simpleperf
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2016-12-15 12:00:44 -0800
committerYabin Cui <yabinc@google.com>2016-12-16 13:01:23 -0800
commite2f1078c54cc4bd81e45b5ca3c88ed0fdfd8cbc7 (patch)
tree04c94f15438a97cc35df887fa00eae62ac5171a4 /simpleperf
parent43b28bc67b04389bc8a803f099e1daada08b969c (diff)
downloadextras-e2f1078c54cc4bd81e45b5ca3c88ed0fdfd8cbc7.tar.gz
simpleperf: merge dumped symbols with symbols read from file system.
Bug: http://b/32340274 Test: run simpleperf_unit_test. Change-Id: Icb96d4778cf527720b24aed58699da05b29c1bd4
Diffstat (limited to 'simpleperf')
-rw-r--r--simpleperf/cmd_report_test.cpp7
-rw-r--r--simpleperf/dso.cpp50
-rwxr-xr-xsimpleperf/testdata/data/t2bin0 -> 8503 bytes
3 files changed, 41 insertions, 16 deletions
diff --git a/simpleperf/cmd_report_test.cpp b/simpleperf/cmd_report_test.cpp
index 18c8deab..f445bd5a 100644
--- a/simpleperf/cmd_report_test.cpp
+++ b/simpleperf/cmd_report_test.cpp
@@ -343,6 +343,13 @@ TEST_F(ReportCommandTest, report_dumped_symbols) {
ASSERT_NE(content.find("memcpy"), std::string::npos);
}
+TEST_F(ReportCommandTest, report_dumped_symbols_with_symfs_dir) {
+ // Check if we can report symbols when they appear both in perf.data and symfs dir.
+ Report(PERF_DATA_WITH_SYMBOLS, {"--symfs", GetTestDataDir()});
+ ASSERT_TRUE(success);
+ ASSERT_NE(content.find("main"), std::string::npos);
+}
+
TEST_F(ReportCommandTest, report_sort_vaddr_in_file) {
Report(PERF_DATA, {"--sort", "vaddr_in_file"});
ASSERT_TRUE(success);
diff --git a/simpleperf/dso.cpp b/simpleperf/dso.cpp
index d52c445f..9091584d 100644
--- a/simpleperf/dso.cpp
+++ b/simpleperf/dso.cpp
@@ -251,13 +251,22 @@ uint64_t Dso::MinVirtualAddress() {
return min_vaddr_;
}
+static std::vector<Symbol> MergeSortedSymbols(const std::vector<Symbol>& s1,
+ const std::vector<Symbol>& s2) {
+ std::vector<Symbol> result;
+ std::set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), std::back_inserter(result),
+ Symbol::CompareValueByAddr);
+ return result;
+}
+
void Dso::Load() {
is_loaded_ = true;
+ std::vector<Symbol> dumped_symbols;
if (!symbols_.empty()) {
- // If symbols has been read from file feature section of perf.data, no
- // need to load them from file system.
- // TODO: combine symbols in file feature section and in file system.
- return;
+ // If symbols has been read from file feature section of perf.data, move it to
+ // dumped_symbols, so later we can merge them with symbols read from file system.
+ dumped_symbols = std::move(symbols_);
+ symbols_.clear();
}
bool result = false;
switch (type_) {
@@ -281,6 +290,15 @@ void Dso::Load() {
FixupSymbolLength();
} else {
symbols_.clear();
+ }
+
+ if (symbols_.empty()) {
+ symbols_ = std::move(dumped_symbols);
+ } else if (!dumped_symbols.empty()) {
+ symbols_ = MergeSortedSymbols(symbols_, dumped_symbols);
+ }
+
+ if (symbols_.empty()) {
LOG(DEBUG) << "failed to load dso: " << path_;
}
}
@@ -344,18 +362,18 @@ bool Dso::LoadKernel() {
symbols_.clear();
return false;
}
- } else {
- if (!build_id.IsEmpty()) {
- BuildId real_build_id;
- if (!GetKernelBuildId(&real_build_id)) {
- return false;
- }
- bool match = (build_id == real_build_id);
- if (!match) {
- LOG(WARNING) << "failed to read symbols from /proc/kallsyms: Build id "
- << "mismatch";
- return false;
- }
+ } else if (!build_id.IsEmpty()) {
+ // Try /proc/kallsyms only when build_id matches. Otherwise, it is likely to use
+ // /proc/kallsyms on host for perf.data recorded on device.
+ BuildId real_build_id;
+ if (!GetKernelBuildId(&real_build_id)) {
+ return false;
+ }
+ bool match = (build_id == real_build_id);
+ if (!match) {
+ LOG(WARNING) << "failed to read symbols from /proc/kallsyms: Build id "
+ << "mismatch";
+ return false;
}
std::string kallsyms;
diff --git a/simpleperf/testdata/data/t2 b/simpleperf/testdata/data/t2
new file mode 100755
index 00000000..bc7a5054
--- /dev/null
+++ b/simpleperf/testdata/data/t2
Binary files differ