No caller sets this to `true`. Initially added for and set by `SymbolFileDWARFDebugMap` (see `616f490777a4f35269a23abee851680134050065`). This was then removed shortly after in: ``` commit762f7135e2Author: Greg Clayton <gclayton@apple.com> Date: Sun Sep 18 18:59:15 2011 +0000 Don't put modules for .o files into the global shared module list. We used to do this because we needed to find the shared pointer for a .o file when the .o file's module was needed in a SymbolContext since the module in a symbol context was a shared pointer. Now that we are using intrusive pointers we don't have this limitation anymore since any instrusive shared pointer can be made from a pointer to an object all on its own. ``` At this point it's more of a foot-gun, because forcing it to true has potentially significant performance implications (e.g.,a5eaa05dce)
176 lines
6.0 KiB
C++
176 lines
6.0 KiB
C++
//===-- ModuleListTest.cpp ------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Core/ModuleList.h"
|
|
#include "TestingSupport/SubsystemRAII.h"
|
|
#include "TestingSupport/TestUtilities.h"
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Core/ModuleSpec.h"
|
|
#include "lldb/Host/FileSystem.h"
|
|
#include "lldb/Utility/ArchSpec.h"
|
|
#include "lldb/Utility/UUID.h"
|
|
|
|
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
// Test that when we already have a module in the shared_module_list with a
|
|
// specific UUID, the next call to GetSharedModule with a module_spec with the
|
|
// same UUID should return the existing module instead of creating a new one.
|
|
TEST(ModuleListTest, GetSharedModuleReusesExistingModuleWithSameUUID) {
|
|
SubsystemRAII<FileSystem, ObjectFileELF> subsystems;
|
|
|
|
auto ExpectedFile = TestFile::fromYaml(R"(
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS64
|
|
Data: ELFDATA2LSB
|
|
Type: ET_DYN
|
|
Machine: EM_X86_64
|
|
Sections:
|
|
- Name: .text
|
|
Type: SHT_PROGBITS
|
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
|
AddressAlign: 0x0000000000000010
|
|
...
|
|
)");
|
|
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
|
|
|
|
// First, let's verify that calling GetSharedModule twice with the same
|
|
// module_spec returns the same module pointer
|
|
|
|
ModuleSP first_module;
|
|
bool first_did_create = false;
|
|
Status error_first = ModuleList::GetSharedModule(
|
|
ExpectedFile->moduleSpec(), first_module, nullptr, &first_did_create);
|
|
|
|
// Second call with the same spec
|
|
ModuleSP second_module;
|
|
bool second_did_create = false;
|
|
Status error_second = ModuleList::GetSharedModule(
|
|
ExpectedFile->moduleSpec(), second_module, nullptr, &second_did_create);
|
|
|
|
if (error_first.Success() && error_second.Success()) {
|
|
// If both succeeded, verify they're the same module
|
|
EXPECT_EQ(first_module.get(), second_module.get())
|
|
<< "GetSharedModule should return the same module for the same spec";
|
|
EXPECT_TRUE(first_did_create) << "First call should create the module";
|
|
EXPECT_FALSE(second_did_create)
|
|
<< "Second call should reuse the existing module";
|
|
}
|
|
}
|
|
|
|
// Test that UUID-based lookup finds existing modules
|
|
TEST(ModuleListTest, FindSharedModuleByUUID) {
|
|
SubsystemRAII<FileSystem, ObjectFileELF> subsystems;
|
|
|
|
auto ExpectedFile = TestFile::fromYaml(R"(
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS64
|
|
Data: ELFDATA2LSB
|
|
Type: ET_DYN
|
|
Machine: EM_X86_64
|
|
Sections:
|
|
- Name: .text
|
|
Type: SHT_PROGBITS
|
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
|
AddressAlign: 0x0000000000000010
|
|
...
|
|
)");
|
|
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
|
|
|
|
// Create and add a module to the shared module list using the moduleSpec()
|
|
ModuleSP created_module;
|
|
bool did_create = false;
|
|
Status error = ModuleList::GetSharedModule(
|
|
ExpectedFile->moduleSpec(), created_module, nullptr, &did_create);
|
|
|
|
if (error.Success() && created_module) {
|
|
// Get the UUID of the created module
|
|
UUID module_uuid = created_module->GetUUID();
|
|
|
|
if (module_uuid.IsValid()) {
|
|
// Now try to find the module by UUID
|
|
ModuleSP found_module = ModuleList::FindSharedModule(module_uuid);
|
|
|
|
ASSERT_NE(found_module.get(), nullptr)
|
|
<< "FindSharedModule should find the module by UUID";
|
|
EXPECT_EQ(found_module.get(), created_module.get())
|
|
<< "FindSharedModule should return the same module instance";
|
|
EXPECT_EQ(found_module->GetUUID(), module_uuid)
|
|
<< "Found module should have the same UUID";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test that GetSharedModule with UUID finds existing module even with different
|
|
// path
|
|
TEST(ModuleListTest, GetSharedModuleByUUIDIgnoresPath) {
|
|
SubsystemRAII<FileSystem, ObjectFileELF> subsystems;
|
|
|
|
auto ExpectedFile = TestFile::fromYaml(R"(
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS64
|
|
Data: ELFDATA2LSB
|
|
Type: ET_DYN
|
|
Machine: EM_X86_64
|
|
Sections:
|
|
- Name: .text
|
|
Type: SHT_PROGBITS
|
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
|
AddressAlign: 0x0000000000000010
|
|
...
|
|
)");
|
|
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
|
|
|
|
// Create and add a module to the shared module list
|
|
ModuleSP first_module;
|
|
bool first_did_create = false;
|
|
Status first_error = ModuleList::GetSharedModule(
|
|
ExpectedFile->moduleSpec(), first_module, nullptr, &first_did_create);
|
|
|
|
if (first_error.Success() && first_module) {
|
|
UUID module_uuid = first_module->GetUUID();
|
|
|
|
if (module_uuid.IsValid()) {
|
|
// Now try to get a module with the same UUID but different path
|
|
ModuleSpec second_spec;
|
|
second_spec.GetFileSpec() = FileSpec("/different/path/to/module.so");
|
|
second_spec.GetArchitecture() = ArchSpec("x86_64-pc-linux");
|
|
second_spec.GetUUID() = module_uuid;
|
|
|
|
ModuleSP second_module;
|
|
bool second_did_create = false;
|
|
Status second_error = ModuleList::GetSharedModule(
|
|
second_spec, second_module, nullptr, &second_did_create);
|
|
|
|
if (second_error.Success() && second_module) {
|
|
// If we got a module back, check if it's the same one
|
|
bool is_same_module = (second_module.get() == first_module.get());
|
|
|
|
// Document the behavior: ideally UUID should take precedence
|
|
// and return the existing module
|
|
EXPECT_TRUE(is_same_module)
|
|
<< "GetSharedModule with matching UUID should return existing "
|
|
"module, "
|
|
<< "even with different path (per PR #160199)";
|
|
|
|
if (is_same_module) {
|
|
EXPECT_FALSE(second_did_create)
|
|
<< "Should not create a new module when UUID matches";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|