summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2020-11-10 13:11:01 -0800
committerYabin Cui <yabinc@google.com>2020-11-11 10:38:47 -0800
commitc13ff898d0876060bf425f4be0da1ecbda51052d (patch)
tree9e03d39390535c0bac65c7d26670caacb36c5744
parentee9f8c79e104eeb328cfb02ce126171b4531146a (diff)
downloadextras-c13ff898d0876060bf425f4be0da1ecbda51052d.tar.gz
simpleperf: use kernel start address in kernel mmap record.
The kernel start address is used to match with the start address in .text section in vmlinux. It works even when kernel address space layout randomization is used. Bug: 172933381 Test: run simpleperf_unit_test Change-Id: I3eb2bee8dd30b049504f4ec6f8f4b6d742cdd6b5
-rw-r--r--simpleperf/cmd_record_test.cpp3
-rw-r--r--simpleperf/environment.cpp23
-rw-r--r--simpleperf/environment_test.cpp12
-rw-r--r--simpleperf/thread_tree.cpp3
-rw-r--r--simpleperf/thread_tree.h2
5 files changed, 38 insertions, 5 deletions
diff --git a/simpleperf/cmd_record_test.cpp b/simpleperf/cmd_record_test.cpp
index 917108af..cf228ae0 100644
--- a/simpleperf/cmd_record_test.cpp
+++ b/simpleperf/cmd_record_test.cpp
@@ -156,8 +156,7 @@ TEST(record_cmd, dump_kernel_mmap) {
for (auto& record : records) {
if (record->type() == PERF_RECORD_MMAP) {
const MmapRecord* mmap_record = static_cast<const MmapRecord*>(record.get());
- if (strcmp(mmap_record->filename, DEFAULT_KERNEL_MMAP_NAME) == 0 ||
- strcmp(mmap_record->filename, DEFAULT_KERNEL_MMAP_NAME_PERF) == 0) {
+ if (android::base::StartsWith(mmap_record->filename, DEFAULT_KERNEL_MMAP_NAME)) {
have_kernel_mmap = true;
break;
}
diff --git a/simpleperf/environment.cpp b/simpleperf/environment.cpp
index 9f3fd3bc..f3333ca1 100644
--- a/simpleperf/environment.cpp
+++ b/simpleperf/environment.cpp
@@ -175,10 +175,33 @@ static std::vector<KernelMmap> GetModulesInUse() {
return module_mmaps;
}
+static uint64_t GetKernelStartAddress() {
+ FILE* fp = fopen("/proc/kallsyms", "re");
+ if (fp == nullptr) {
+ return 0;
+ }
+ LineReader reader(fp);
+ char* line;
+ while ((line = reader.ReadLine()) != nullptr) {
+ if (strstr(line, "_stext") != nullptr) {
+ uint64_t addr;
+ if (sscanf(line, "%" PRIx64, &addr) == 1) {
+ return addr;
+ }
+ }
+ }
+ return 0;
+}
+
void GetKernelAndModuleMmaps(KernelMmap* kernel_mmap, std::vector<KernelMmap>* module_mmaps) {
kernel_mmap->name = DEFAULT_KERNEL_MMAP_NAME;
kernel_mmap->start_addr = 0;
kernel_mmap->len = std::numeric_limits<uint64_t>::max();
+ if (uint64_t kstart_addr = GetKernelStartAddress(); kstart_addr != 0) {
+ kernel_mmap->name = std::string(DEFAULT_KERNEL_MMAP_NAME) + "_stext";
+ kernel_mmap->start_addr = kstart_addr;
+ kernel_mmap->len = std::numeric_limits<uint64_t>::max() - kstart_addr;
+ }
kernel_mmap->filepath = kernel_mmap->name;
*module_mmaps = GetModulesInUse();
for (auto& map : *module_mmaps) {
diff --git a/simpleperf/environment_test.cpp b/simpleperf/environment_test.cpp
index 8188ddb4..dd9d39f6 100644
--- a/simpleperf/environment_test.cpp
+++ b/simpleperf/environment_test.cpp
@@ -23,6 +23,8 @@
#include "dso.h"
#include "environment.h"
#include "get_test_data.h"
+#include "test_util.h"
+#include "thread_tree.h"
namespace fs = std::filesystem;
@@ -111,3 +113,13 @@ TEST(environment, GetModuleBuildId) {
ASSERT_TRUE(GetModuleBuildId("fake_kernel_module", &build_id, GetTestData("sysfs")));
ASSERT_EQ(build_id, BuildId("3e0ba155286f3454"));
}
+
+TEST(environment, GetKernelAndModuleMmaps) {
+ TEST_REQUIRE_ROOT();
+ KernelMmap kernel_mmap;
+ std::vector<KernelMmap> module_mmaps;
+ GetKernelAndModuleMmaps(&kernel_mmap, &module_mmaps);
+ // The kernel map should contain the kernel start address.
+ ASSERT_EQ(kernel_mmap.name, std::string(DEFAULT_KERNEL_MMAP_NAME) + "_stext");
+ ASSERT_GT(kernel_mmap.start_addr, 0);
+}
diff --git a/simpleperf/thread_tree.cpp b/simpleperf/thread_tree.cpp
index 1818ff41..107e34d7 100644
--- a/simpleperf/thread_tree.cpp
+++ b/simpleperf/thread_tree.cpp
@@ -22,6 +22,7 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include "perf_event.h"
#include "record.h"
@@ -133,7 +134,7 @@ void ThreadTree::AddKernelMap(uint64_t start_addr, uint64_t len, uint64_t pgoff,
}
Dso* ThreadTree::FindKernelDsoOrNew(const std::string& filename) {
- if (filename == DEFAULT_KERNEL_MMAP_NAME || filename == DEFAULT_KERNEL_MMAP_NAME_PERF) {
+ if (android::base::StartsWith(filename, DEFAULT_KERNEL_MMAP_NAME)) {
return kernel_dso_.get();
}
auto it = module_dso_tree_.find(filename);
diff --git a/simpleperf/thread_tree.h b/simpleperf/thread_tree.h
index 2c9a362e..aadfe71b 100644
--- a/simpleperf/thread_tree.h
+++ b/simpleperf/thread_tree.h
@@ -29,8 +29,6 @@
struct Record;
constexpr char DEFAULT_KERNEL_MMAP_NAME[] = "[kernel.kallsyms]";
-// Seen in perf.data file generated by perf.
-constexpr char DEFAULT_KERNEL_MMAP_NAME_PERF[] = "[kernel.kallsyms]_text";
constexpr char DEFAULT_EXECNAME_FOR_THREAD_MMAP[] = "//anon";
namespace simpleperf {