diff options
author | Tamas Zsoldos <tamas.zsoldos@arm.com> | 2024-01-26 14:51:06 +0100 |
---|---|---|
committer | Tamas Zsoldos <tamas.zsoldos@arm.com> | 2024-01-30 09:58:32 +0100 |
commit | 6a1e5e9d5a4e531b00c0185a00d380ace029c7b1 (patch) | |
tree | 27ce8e8b843178f5614af615cb4bd4cf35052214 /simpleperf | |
parent | 5ce0102ccd44e70b6d10e6f23d9b2e924081b4f1 (diff) | |
download | extras-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.cpp | 7 | ||||
-rw-r--r-- | simpleperf/cmd_inject_test.cpp | 20 | ||||
-rw-r--r-- | simpleperf/runtest/Android.bp | 6 | ||||
-rw-r--r-- | simpleperf/testdata/etm/etm_test_loop_small | bin | 0 -> 4008 bytes | |||
-rw-r--r-- | simpleperf/testdata/etm/perf_for_small_binary.data | bin | 0 -> 22680 bytes | |||
-rw-r--r-- | simpleperf/testdata/etm/perf_inject_small.data | 32 |
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 Binary files differnew file mode 100644 index 00000000..600bf9eb --- /dev/null +++ b/simpleperf/testdata/etm/etm_test_loop_small diff --git a/simpleperf/testdata/etm/perf_for_small_binary.data b/simpleperf/testdata/etm/perf_for_small_binary.data Binary files differnew file mode 100644 index 00000000..9b012e50 --- /dev/null +++ b/simpleperf/testdata/etm/perf_for_small_binary.data 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 + |