diff options
author | Snehasish Kumar <snehasishk@google.com> | 2022-03-02 17:28:09 -0800 |
---|---|---|
committer | Snehasish Kumar <snehasishk@google.com> | 2022-03-04 11:10:08 -0800 |
commit | 11314f405903482c5a09e29922db80305e7c20d4 (patch) | |
tree | 11817fd4df72b3ee1251d3f2345e46f2a7f8d803 /llvm/unittests/ProfileData/MemProfTest.cpp | |
parent | 76ec69a911c696feb9d315fa8335406556718e89 (diff) | |
download | llvm-11314f405903482c5a09e29922db80305e7c20d4.zip llvm-11314f405903482c5a09e29922db80305e7c20d4.tar.gz llvm-11314f405903482c5a09e29922db80305e7c20d4.tar.bz2 |
[memprof] Filter out callstack frames which cannot be symbolized.
This patch filters out callstack frames which can't be symbolized or if
the frames belong to the runtime. Symbolization may not be possible if
debug information is unavailable or if the addresses are from a shared
library. For now we only support optimization of the main binary which
is statically linked to the compiler runtime.
Differential Revision: https://reviews.llvm.org/D120860
Diffstat (limited to 'llvm/unittests/ProfileData/MemProfTest.cpp')
-rw-r--r-- | llvm/unittests/ProfileData/MemProfTest.cpp | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/llvm/unittests/ProfileData/MemProfTest.cpp b/llvm/unittests/ProfileData/MemProfTest.cpp index 5fee174..fd31042 100644 --- a/llvm/unittests/ProfileData/MemProfTest.cpp +++ b/llvm/unittests/ProfileData/MemProfTest.cpp @@ -62,6 +62,7 @@ struct MockInfo { uint32_t Line; uint32_t StartLine; uint32_t Column; + std::string FileName = "valid/path.cc"; }; DIInliningInfo makeInliningInfo(std::initializer_list<MockInfo> MockFrames) { DIInliningInfo Result; @@ -71,6 +72,7 @@ DIInliningInfo makeInliningInfo(std::initializer_list<MockInfo> MockFrames) { Frame.Line = Item.Line; Frame.StartLine = Item.StartLine; Frame.Column = Item.Column; + Frame.FileName = Item.FileName; Result.addFrame(Frame); } return Result; @@ -234,4 +236,58 @@ TEST(MemProf, RecordSerializationRoundTrip) { EXPECT_THAT(GotRecords[0], EqualsRecord(Records[0])); EXPECT_THAT(GotRecords[1], EqualsRecord(Records[1])); } + +TEST(MemProf, SymbolizationFilter) { + std::unique_ptr<MockSymbolizer> Symbolizer(new MockSymbolizer()); + + EXPECT_CALL(*Symbolizer, symbolizeInlinedCode(SectionedAddress{0x1000}, + specifier(), false)) + .Times(1) // once since we don't lookup invalid PCs repeatedly. + .WillRepeatedly(Return(makeInliningInfo({ + {"malloc", 70, 57, 3, "memprof/memprof_malloc_linux.cpp"}, + }))); + + EXPECT_CALL(*Symbolizer, symbolizeInlinedCode(SectionedAddress{0x2000}, + specifier(), false)) + .Times(1) // once since we don't lookup invalid PCs repeatedly. + .WillRepeatedly(Return(makeInliningInfo({ + {"new", 70, 57, 3, "memprof/memprof_new_delete.cpp"}, + }))); + + EXPECT_CALL(*Symbolizer, symbolizeInlinedCode(SectionedAddress{0x3000}, + specifier(), false)) + .Times(1) // once since we don't lookup invalid PCs repeatedly. + .WillRepeatedly(Return(makeInliningInfo({ + {DILineInfo::BadString, 0, 0, 0}, + }))); + + EXPECT_CALL(*Symbolizer, symbolizeInlinedCode(SectionedAddress{0x4000}, + specifier(), false)) + .Times(1) + .WillRepeatedly(Return(makeInliningInfo({ + {"foo", 10, 5, 30}, + }))); + + CallStackMap CSM; + CSM[0x1] = {0x1000, 0x2000, 0x3000, 0x4000}; + // This entry should be dropped since all PCs are either not + // symbolizable or belong to the runtime. + CSM[0x2] = {0x1000, 0x2000}; + + llvm::MapVector<uint64_t, MemInfoBlock> Prof; + Prof[0x1].AllocCount = 1; + Prof[0x2].AllocCount = 1; + + auto Seg = makeSegments(); + + RawMemProfReader Reader(std::move(Symbolizer), Seg, Prof, CSM); + + std::vector<MemProfRecord> Records; + for (const MemProfRecord &R : Reader) { + Records.push_back(R); + } + ASSERT_EQ(Records.size(), 1U); + ASSERT_EQ(Records[0].CallStack.size(), 1U); + EXPECT_THAT(Records[0].CallStack[0], FrameContains("foo", 5U, 30U, false)); +} } // namespace |