summaryrefslogtreecommitdiff
path: root/simpleperf
diff options
context:
space:
mode:
authorTamas Zsoldos <tamas.zsoldos@arm.com>2024-01-26 14:51:06 +0100
committerTamas Zsoldos <tamas.zsoldos@arm.com>2024-01-30 09:58:32 +0100
commit6a1e5e9d5a4e531b00c0185a00d380ace029c7b1 (patch)
tree27ce8e8b843178f5614af615cb4bd4cf35052214 /simpleperf
parent5ce0102ccd44e70b6d10e6f23d9b2e924081b4f1 (diff)
downloadextras-6a1e5e9d5a4e531b00c0185a00d380ace029c7b1.tar.gz
simpleperf: Fix ReadTargetMemory caching.
In case we found memory, but it was unsuitable for caching, set the cached buffer's map to null, forcing us to take the slow path again. Without this change, the buffer itself is set to null. However, the fast path cannot tell if there was no memory found or we just did not want to cache it. This can cause an address range to succeeded at first, but fail on a second try. As a test and a practical example, a binary that is smaller than a page is added. In this case the memory found by ReadTargetMemory will never be large enough to contain the whole mapping, preventing it from being cached. Without this change, simpleperf inject generates almost no output, with this change it generates the expected full output. Test: simpleperf_unit_test Change-Id: Ibc8d6bf6476b473b99fc787a1789344bda334ce3
Diffstat (limited to 'simpleperf')
-rw-r--r--simpleperf/ETMDecoder.cpp7
-rw-r--r--simpleperf/cmd_inject_test.cpp20
-rw-r--r--simpleperf/runtest/Android.bp6
-rw-r--r--simpleperf/testdata/etm/etm_test_loop_smallbin0 -> 4008 bytes
-rw-r--r--simpleperf/testdata/etm/perf_for_small_binary.databin0 -> 22680 bytes
-rw-r--r--simpleperf/testdata/etm/perf_inject_small.data32
6 files changed, 59 insertions, 6 deletions
diff --git a/simpleperf/ETMDecoder.cpp b/simpleperf/ETMDecoder.cpp
index 822cc6cd..96b4f1a8 100644
--- a/simpleperf/ETMDecoder.cpp
+++ b/simpleperf/ETMDecoder.cpp
@@ -292,8 +292,13 @@ class MemAccess : public ITargetMemAccess {
if (memory != nullptr && memory->getBufferSize() > map->pgoff &&
(memory->getBufferSize() - map->pgoff >= map->len)) {
data.buffer = memory->getBufferStart() + map->pgoff;
- } else {
+ } else if (memory == nullptr) {
data.buffer = nullptr;
+ } else {
+ // Memory was found, but the buffer is not good enough to be
+ // cached. "Invalidate" the cache by setting the map to
+ // null.
+ data.buffer_map = nullptr;
}
}
}
diff --git a/simpleperf/cmd_inject_test.cpp b/simpleperf/cmd_inject_test.cpp
index bdc2820f..9bb1efba 100644
--- a/simpleperf/cmd_inject_test.cpp
+++ b/simpleperf/cmd_inject_test.cpp
@@ -51,10 +51,10 @@ static bool RunInjectCmd(std::vector<std::string>&& args, std::string* output) {
return true;
}
-static void CheckMatchingExpectedData(std::string& data) {
+static void CheckMatchingExpectedData(const std::string& name, std::string& data) {
std::string expected_data;
ASSERT_TRUE(android::base::ReadFileToString(
- GetTestData(std::string("etm") + OS_PATH_SEPARATOR + "perf_inject.data"), &expected_data));
+ GetTestData(std::string("etm") + OS_PATH_SEPARATOR + name), &expected_data));
data.erase(std::remove(data.begin(), data.end(), '\r'), data.end());
ASSERT_EQ(data, expected_data);
}
@@ -64,7 +64,7 @@ TEST(cmd_inject, smoke) {
ASSERT_TRUE(RunInjectCmd({}, &data));
// Test that we can find instr range in etm_test_loop binary.
ASSERT_NE(data.find("etm_test_loop"), std::string::npos);
- CheckMatchingExpectedData(data);
+ CheckMatchingExpectedData("perf_inject.data", data);
}
TEST(cmd_inject, binary_option) {
@@ -97,7 +97,7 @@ TEST(cmd_inject, output_option) {
ASSERT_TRUE(RunInjectCmd({"--output", "branch-list", "-o", tmpfile.path}));
std::string autofdo_data;
ASSERT_TRUE(RunInjectCmd({"-i", tmpfile.path, "--output", "autofdo"}, &autofdo_data));
- CheckMatchingExpectedData(autofdo_data);
+ CheckMatchingExpectedData("perf_inject.data", autofdo_data);
}
TEST(cmd_inject, skip_empty_output_file) {
@@ -139,7 +139,7 @@ TEST(cmd_inject, unformatted_trace) {
ASSERT_TRUE(RunInjectCmd({"-i", perf_with_unformatted_trace}, &data));
// Test that we can find instr range in etm_test_loop binary.
ASSERT_NE(data.find("etm_test_loop"), std::string::npos);
- CheckMatchingExpectedData(data);
+ CheckMatchingExpectedData("perf_inject.data", data);
}
TEST(cmd_inject, multiple_input_files) {
@@ -263,3 +263,13 @@ TEST(cmd_inject, read_lbr_data) {
&data));
ASSERT_NE(data.find("194d->1940:706"), data.npos);
}
+
+TEST(cmd_inject, inject_small_binary) {
+ // etm_test_loop_small, a binary compiled with
+ // "-Wl,-z,noseparate-code", where the file is smaller than its text
+ // section mapped into memory.
+ std::string data;
+ std::string perf_data = GetTestData("etm/perf_for_small_binary.data");
+ ASSERT_TRUE(RunInjectCmd({"-i", perf_data}, &data));
+ CheckMatchingExpectedData("perf_inject_small.data", data);
+}
diff --git a/simpleperf/runtest/Android.bp b/simpleperf/runtest/Android.bp
index 53fdfefe..62a0aeeb 100644
--- a/simpleperf/runtest/Android.bp
+++ b/simpleperf/runtest/Android.bp
@@ -103,3 +103,9 @@ cc_binary {
srcs: ["etm_test_loop.cpp"],
// afdo: true,
}
+
+cc_binary {
+ name: "etm_test_loop_small",
+ srcs: ["etm_test_loop.cpp"],
+ ldflags: ["-Wl,-z,noseparate-code"],
+}
diff --git a/simpleperf/testdata/etm/etm_test_loop_small b/simpleperf/testdata/etm/etm_test_loop_small
new file mode 100644
index 00000000..600bf9eb
--- /dev/null
+++ b/simpleperf/testdata/etm/etm_test_loop_small
Binary files differ
diff --git a/simpleperf/testdata/etm/perf_for_small_binary.data b/simpleperf/testdata/etm/perf_for_small_binary.data
new file mode 100644
index 00000000..9b012e50
--- /dev/null
+++ b/simpleperf/testdata/etm/perf_for_small_binary.data
Binary files differ
diff --git a/simpleperf/testdata/etm/perf_inject_small.data b/simpleperf/testdata/etm/perf_inject_small.data
new file mode 100644
index 00000000..560b4927
--- /dev/null
+++ b/simpleperf/testdata/etm/perf_inject_small.data
@@ -0,0 +1,32 @@
+14
+14b4-14c4:1
+14c8-14fc:1
+150c-151c:1
+156c-1580:1
+1584-158c:1
+1590-15a4:10
+15a8-15b0:10
+15b4-15c4:2
+15c8-15dc:200
+15e0-15e0:2
+15e4-15f4:8
+15f8-160c:8000
+1610-1610:8
+1640-164c:1
+0
+12
+14c4->14c8:1
+14fc->150c:1
+151c->1640:1
+1580->15a8:1
+158c->0:1
+15a4->1584:1
+15b0->15e4:8
+15dc->15c8:198
+15e0->1590:2
+160c->15f8:7992
+1610->1590:8
+164c->0:1
+// build_id: 0xb9988f5e72de4b2580f98bef0ae8e4a000000000
+// /data/local/tmp/etm/etm_test_loop_small
+