diff options
author | Greg Clayton <gclayton@fb.com> | 2019-12-03 16:44:02 -0800 |
---|---|---|
committer | Greg Clayton <gclayton@fb.com> | 2019-12-05 16:49:53 -0800 |
commit | aeda128a96c4ac9eecef7563f4cf07dfcd2af0db (patch) | |
tree | 2452f0050027c3a641fee592fdfa16b0bfc9e9fc /llvm/unittests/DebugInfo | |
parent | 6470497817eafe3fe2d15e11ade78fd99753d7ca (diff) | |
download | bcm5719-llvm-aeda128a96c4ac9eecef7563f4cf07dfcd2af0db.tar.gz bcm5719-llvm-aeda128a96c4ac9eecef7563f4cf07dfcd2af0db.zip |
Add lookup functions for efficient lookups of addresses when using GsymReader classes.
Summary:
Lookup functions are designed to not fully decode a FunctionInfo, LineTable or InlineInfo, they decode only what is needed into a LookupResult object. This allows lookups to avoid costly memory allocations and avoid parsing large amounts of information one a suitable match is found.
LookupResult objects contain the address that was looked up, the concrete function address range, the name of the concrete function, and a list of source locations. One for each inline function, and one for the concrete function. This allows one address to turn into multiple frames and improves the signal you get when symbolicating addresses in GSYM files.
Reviewers: labath, aprantl
Subscribers: mgorny, hiraditya, llvm-commits, lldb-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70993
Diffstat (limited to 'llvm/unittests/DebugInfo')
-rw-r--r-- | llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp b/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp index 9fd8edf6a10..bee1d4091cd 100644 --- a/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp +++ b/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp @@ -20,8 +20,10 @@ #include "llvm/DebugInfo/GSYM/StringTable.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Endian.h" +#include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" +#include "gmock/gmock.h" #include <string> using namespace llvm; @@ -1302,3 +1304,100 @@ TEST(GSYMTest, TestGsymReader) { "address 0x1030 not in GSYM"); } } + +TEST(GSYMTest, TestGsymLookups) { + // Test creating a GSYM file with a function that has a inline information. + // Verify that lookups work correctly. Lookups do not decode the entire + // FunctionInfo or InlineInfo, they only extract information needed for the + // lookup to happen which avoids allocations which can slow down + // symbolication. + GsymCreator GC; + FunctionInfo FI(0x1000, 0x100, GC.insertString("main")); + const auto ByteOrder = support::endian::system_endianness(); + FI.OptLineTable = LineTable(); + const uint32_t MainFileIndex = GC.insertFile("/tmp/main.c"); + const uint32_t FooFileIndex = GC.insertFile("/tmp/foo.h"); + FI.OptLineTable->push(LineEntry(0x1000, MainFileIndex, 5)); + FI.OptLineTable->push(LineEntry(0x1010, FooFileIndex, 10)); + FI.OptLineTable->push(LineEntry(0x1012, FooFileIndex, 20)); + FI.OptLineTable->push(LineEntry(0x1014, FooFileIndex, 11)); + FI.OptLineTable->push(LineEntry(0x1016, FooFileIndex, 30)); + FI.OptLineTable->push(LineEntry(0x1018, FooFileIndex, 12)); + FI.OptLineTable->push(LineEntry(0x1020, MainFileIndex, 8)); + FI.Inline = InlineInfo(); + + FI.Inline->Name = GC.insertString("inline1"); + FI.Inline->CallFile = MainFileIndex; + FI.Inline->CallLine = 6; + FI.Inline->Ranges.insert(AddressRange(0x1010, 0x1020)); + InlineInfo Inline2; + Inline2.Name = GC.insertString("inline2"); + Inline2.CallFile = FooFileIndex; + Inline2.CallLine = 33; + Inline2.Ranges.insert(AddressRange(0x1012, 0x1014)); + FI.Inline->Children.emplace_back(Inline2); + InlineInfo Inline3; + Inline3.Name = GC.insertString("inline3"); + Inline3.CallFile = FooFileIndex; + Inline3.CallLine = 35; + Inline3.Ranges.insert(AddressRange(0x1016, 0x1018)); + FI.Inline->Children.emplace_back(Inline3); + GC.addFunctionInfo(std::move(FI)); + Error FinalizeErr = GC.finalize(llvm::nulls()); + ASSERT_FALSE(FinalizeErr); + SmallString<512> Str; + raw_svector_ostream OutStrm(Str); + FileWriter FW(OutStrm, ByteOrder); + llvm::Error Err = GC.encode(FW); + ASSERT_FALSE((bool)Err); + Expected<GsymReader> GR = GsymReader::copyBuffer(OutStrm.str()); + ASSERT_TRUE(bool(GR)); + + // Verify inline info is correct when doing lookups. + auto LR = GR->lookup(0x1000); + ASSERT_THAT_EXPECTED(LR, Succeeded()); + EXPECT_THAT(LR->Locations, + testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 5})); + LR = GR->lookup(0x100F); + ASSERT_THAT_EXPECTED(LR, Succeeded()); + EXPECT_THAT(LR->Locations, + testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 5})); + + LR = GR->lookup(0x1010); + ASSERT_THAT_EXPECTED(LR, Succeeded()); + + EXPECT_THAT(LR->Locations, + testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 10}, + SourceLocation{"main", "/tmp", "main.c", 6})); + + LR = GR->lookup(0x1012); + ASSERT_THAT_EXPECTED(LR, Succeeded()); + EXPECT_THAT(LR->Locations, + testing::ElementsAre(SourceLocation{"inline2", "/tmp", "foo.h", 20}, + SourceLocation{"inline1", "/tmp", "foo.h", 33}, + SourceLocation{"main", "/tmp", "main.c", 6})); + + LR = GR->lookup(0x1014); + ASSERT_THAT_EXPECTED(LR, Succeeded()); + EXPECT_THAT(LR->Locations, + testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 11}, + SourceLocation{"main", "/tmp", "main.c", 6})); + + LR = GR->lookup(0x1016); + ASSERT_THAT_EXPECTED(LR, Succeeded()); + EXPECT_THAT(LR->Locations, + testing::ElementsAre(SourceLocation{"inline3", "/tmp", "foo.h", 30}, + SourceLocation{"inline1", "/tmp", "foo.h", 35}, + SourceLocation{"main", "/tmp", "main.c", 6})); + + LR = GR->lookup(0x1018); + ASSERT_THAT_EXPECTED(LR, Succeeded()); + EXPECT_THAT(LR->Locations, + testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 12}, + SourceLocation{"main", "/tmp", "main.c", 6})); + + LR = GR->lookup(0x1020); + ASSERT_THAT_EXPECTED(LR, Succeeded()); + EXPECT_THAT(LR->Locations, + testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 8})); +} |