From 7999b4fa48b31f67efa3662443a5c78343eb6f19 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Wed, 5 Sep 2018 23:30:38 +0000 Subject: [PDB] Refactor the PDB symbol classes to fix a reuse bug. The way DIA SDK works is that when you request a symbol, it gets assigned an internal identifier that is unique for the life of the session. You can then use this identifier to get back the same symbol, with all of the same internal state that it had before, even if you "destroyed" the original copy of the object you had. This didn't work properly in our native implementation, and if you destroyed an object for a particular symbol, then requested the same symbol again, it would get assigned a new ID and you'd get a fresh copy of the object. In order to fix this some refactoring had to happen to properly reuse cached objects. Some unittests are added to verify that symbol reuse is taking place, making use of the new unittest input feature. llvm-svn: 341503 --- .../DebugInfo/PDB/NativeSymbolReuseTest.cpp | 128 +++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp (limited to 'llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp') diff --git a/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp b/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp new file mode 100644 index 00000000000..8c98f837142 --- /dev/null +++ b/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp @@ -0,0 +1,128 @@ +//===- NativeSymbolReuseTest.cpp ------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/PDB.h" + +#include "llvm/DebugInfo/PDB/IPDBSession.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" +#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" +#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +#include "llvm/Support/Path.h" + +#include "llvm/Testing/Support/Error.h" +#include "llvm/Testing/Support/SupportHelpers.h" + +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::pdb; + +TEST(NativeSymbolReuseTest, GlobalSymbolReuse) { + SmallString<128> InputsDir = unittest::getInputFileDirectory(); + llvm::sys::path::append(InputsDir, "empty.pdb"); + + std::unique_ptr S; + Error E = pdb::loadDataForPDB(PDB_ReaderType::Native, InputsDir, S); + + ASSERT_THAT_ERROR(std::move(E), Succeeded()); + + SymIndexId GlobalId; + { + auto GS1 = S->getGlobalScope(); + auto GS2 = S->getGlobalScope(); + + GlobalId = GS1->getSymIndexId(); + SymIndexId Id2 = GS1->getSymIndexId(); + EXPECT_EQ(GlobalId, Id2); + } + + { + auto GS3 = S->getGlobalScope(); + + SymIndexId Id3 = GS3->getSymIndexId(); + EXPECT_EQ(GlobalId, Id3); + } +} + +TEST(NativeSymbolReuseTest, CompilandSymbolReuse) { + SmallString<128> InputsDir = unittest::getInputFileDirectory(); + llvm::sys::path::append(InputsDir, "empty.pdb"); + + std::unique_ptr S; + Error E = pdb::loadDataForPDB(PDB_ReaderType::Native, InputsDir, S); + + ASSERT_THAT_ERROR(std::move(E), Succeeded()); + + auto GS = S->getGlobalScope(); + + std::vector CompilandIds; + { + auto Compilands = GS->findAllChildren(); + ASSERT_NE(nullptr, Compilands); + ASSERT_EQ(2, Compilands->getChildCount()); + std::vector Ids2; + + // First try resetting the enumerator, then try destroying the enumerator + // and constructing another one. + while (auto Compiland = Compilands->getNext()) + CompilandIds.push_back(Compiland->getSymIndexId()); + Compilands->reset(); + while (auto Compiland = Compilands->getNext()) + Ids2.push_back(Compiland->getSymIndexId()); + + EXPECT_EQ(CompilandIds, Ids2); + } + + { + auto Compilands = GS->findAllChildren(); + ASSERT_NE(nullptr, Compilands); + ASSERT_EQ(2U, Compilands->getChildCount()); + + std::vector Ids3; + while (auto Compiland = Compilands->getNext()) + Ids3.push_back(Compiland->getSymIndexId()); + + EXPECT_EQ(CompilandIds, Ids3); + } +} + +TEST(NativeSymbolReuseTest, CompilandSymbolReuseBackwards) { + SmallString<128> InputsDir = unittest::getInputFileDirectory(); + llvm::sys::path::append(InputsDir, "empty.pdb"); + + std::unique_ptr S; + Error E = pdb::loadDataForPDB(PDB_ReaderType::Native, InputsDir, S); + + ASSERT_THAT_ERROR(std::move(E), Succeeded()); + + auto GS = S->getGlobalScope(); + + // This time do the first iteration backwards, and make sure that when you + // then iterate them forwards, the IDs come out in reverse. + std::vector CompilandIds; + { + auto Compilands = GS->findAllChildren(); + ASSERT_NE(nullptr, Compilands); + ASSERT_EQ(2U, Compilands->getChildCount()); + + std::vector Ids2; + + for (int I = Compilands->getChildCount() - 1; I >= 0; --I) { + auto Compiland = Compilands->getChildAtIndex(I); + CompilandIds.push_back(Compiland->getSymIndexId()); + } + + while (auto Compiland = Compilands->getNext()) + Ids2.push_back(Compiland->getSymIndexId()); + + auto ReversedIter = llvm::reverse(Ids2); + std::vector Reversed{ReversedIter.begin(), ReversedIter.end()}; + EXPECT_EQ(CompilandIds, Reversed); + } +} -- cgit v1.2.3