aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/ProfileData/MemProfTest.cpp
diff options
context:
space:
mode:
authorSnehasish Kumar <snehasishk@google.com>2022-03-02 17:28:09 -0800
committerSnehasish Kumar <snehasishk@google.com>2022-03-04 11:10:08 -0800
commit11314f405903482c5a09e29922db80305e7c20d4 (patch)
tree11817fd4df72b3ee1251d3f2345e46f2a7f8d803 /llvm/unittests/ProfileData/MemProfTest.cpp
parent76ec69a911c696feb9d315fa8335406556718e89 (diff)
downloadllvm-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.cpp56
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