[lldb] Change the way the shlib directory helper is set (#183637)

This PR changes the way we set the shlib directory helper. Instead of
setting it while initializing the Host plugin, we register it when
initializing the Python plugin. The motivation is that the current
approach is incompatible with the dynamically linked script
interpreters, as they will not have been loaded at the time the Host
plugin is initialized.

The downside of the new approach is that we set the helper after having
initialized the Host plugin, which theoretically introduces a small
window where someone could query the helper before it has been set.
Fortunately the window is pretty small and limited to when we're
initializing plugins, but it's less "pure" than what we had previously.
That said, I think it balances out with removing the plugin include.
This commit is contained in:
Jonas Devlieghere 2026-02-27 15:27:02 -08:00 committed by GitHub
parent 788625757e
commit 329c52c100
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 50 additions and 46 deletions

View File

@ -96,8 +96,10 @@ public:
/// (optionally) replace it with a file spec pointing to a more canonical
/// copy.
using SharedLibraryDirectoryHelper = void(FileSpec &this_file);
static void
SetSharedLibraryDirectoryHelper(SharedLibraryDirectoryHelper *helper);
static void Initialize(SharedLibraryDirectoryHelper *helper = nullptr);
static void Initialize();
static void Terminate();
/// Gets the host target triple.
@ -273,7 +275,9 @@ public:
static llvm::StringRef GetDistributionId() { return llvm::StringRef(); }
protected:
static bool ComputeSharedLibraryDirectory(FileSpec &file_spec);
static bool
ComputeSharedLibraryDirectory(FileSpec &file_spec,
SharedLibraryDirectoryHelper *helper);
static bool ComputeSupportExeDirectory(FileSpec &file_spec);
static bool ComputeProcessTempFileDirectory(FileSpec &file_spec);
static bool ComputeGlobalTempFileDirectory(FileSpec &file_spec);

View File

@ -18,7 +18,7 @@ class HostInfoAIX : public HostInfoPosix {
friend class HostInfoBase;
public:
static void Initialize(SharedLibraryDirectoryHelper *helper = nullptr);
static void Initialize();
static void Terminate();
static FileSpec GetProgramFileSpec();

View File

@ -22,7 +22,7 @@ class HostInfoLinux : public HostInfoPosix {
friend class HostInfoBase;
public:
static void Initialize(SharedLibraryDirectoryHelper *helper = nullptr);
static void Initialize();
static void Terminate();
static llvm::StringRef GetDistributionId();

View File

@ -21,7 +21,7 @@ class HostInfoWindows : public HostInfoBase {
friend class HostInfoBase;
public:
static void Initialize(SharedLibraryDirectoryHelper *helper = nullptr);
static void Initialize();
static void Terminate();
static size_t GetPageSize();

View File

@ -23,14 +23,11 @@ namespace lldb_private {
/// the constructor.
class SystemInitializerCommon : public SystemInitializer {
public:
SystemInitializerCommon(HostInfo::SharedLibraryDirectoryHelper *helper);
SystemInitializerCommon();
~SystemInitializerCommon() override;
llvm::Error Initialize() override;
void Terminate() override;
private:
HostInfo::SharedLibraryDirectoryHelper *m_shlib_dir_helper;
};
} // namespace lldb_private

View File

@ -32,22 +32,9 @@
#define LLDB_PLUGIN(p) LLDB_PLUGIN_DECLARE(p)
#include "Plugins/Plugins.def"
#if LLDB_ENABLE_PYTHON
#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
constexpr lldb_private::HostInfo::SharedLibraryDirectoryHelper
*g_shlib_dir_helper =
lldb_private::ScriptInterpreterPython::SharedLibraryDirectoryHelper;
#else
constexpr lldb_private::HostInfo::SharedLibraryDirectoryHelper
*g_shlib_dir_helper = nullptr;
#endif
using namespace lldb_private;
SystemInitializerFull::SystemInitializerFull()
: SystemInitializerCommon(g_shlib_dir_helper) {}
SystemInitializerFull::SystemInitializerFull() : SystemInitializerCommon() {}
SystemInitializerFull::~SystemInitializerFull() = default;
llvm::Error SystemInitializerFull::Initialize() {

View File

@ -12,9 +12,7 @@
using namespace lldb_private;
void HostInfoAIX::Initialize(SharedLibraryDirectoryHelper *helper) {
HostInfoPosix::Initialize(helper);
}
void HostInfoAIX::Initialize() { HostInfoPosix::Initialize(); }
void HostInfoAIX::Terminate() { HostInfoBase::Terminate(); }

View File

@ -53,6 +53,13 @@ struct HostInfoBaseFields {
llvm::once_flag m_lldb_so_dir_once;
FileSpec m_lldb_so_dir;
#ifndef NDEBUG
/// Used to assert that the shared library helper isn't set after the shlib
/// dir has already been computed.
bool m_lldb_so_dir_computed = false;
#endif
HostInfoBase::SharedLibraryDirectoryHelper *g_shlib_dir_helper = nullptr;
llvm::once_flag m_lldb_support_exe_dir_once;
FileSpec m_lldb_support_exe_dir;
llvm::once_flag m_lldb_headers_dir_once;
@ -75,17 +82,14 @@ struct HostInfoBaseFields {
} // namespace
static HostInfoBaseFields *g_fields = nullptr;
static HostInfoBase::SharedLibraryDirectoryHelper *g_shlib_dir_helper = nullptr;
void HostInfoBase::Initialize(SharedLibraryDirectoryHelper *helper) {
g_shlib_dir_helper = helper;
void HostInfoBase::Initialize() {
g_fields = new HostInfoBaseFields();
LogChannelSystem::Initialize();
}
void HostInfoBase::Terminate() {
LogChannelSystem::Terminate();
g_shlib_dir_helper = nullptr;
delete g_fields;
g_fields = nullptr;
}
@ -125,8 +129,12 @@ HostInfoBase::ParseArchitectureKind(llvm::StringRef kind) {
FileSpec HostInfoBase::GetShlibDir() {
llvm::call_once(g_fields->m_lldb_so_dir_once, []() {
if (!HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir))
if (!HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir,
g_fields->g_shlib_dir_helper))
g_fields->m_lldb_so_dir = FileSpec();
#ifndef NDEBUG
g_fields->m_lldb_so_dir_computed = true;
#endif
Log *log = GetLog(LLDBLog::Host);
LLDB_LOG(log, "shlib dir -> `{0}`", g_fields->m_lldb_so_dir);
});
@ -269,7 +277,18 @@ bool HostInfoBase::ComputePathRelativeToLibrary(FileSpec &file_spec,
return (bool)file_spec.GetDirectory();
}
bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) {
void HostInfoBase::SetSharedLibraryDirectoryHelper(
SharedLibraryDirectoryHelper *helper) {
assert(g_fields &&
"SetSharedLibraryDirectoryHelper called before Initialize");
assert(!g_fields->m_lldb_so_dir_computed &&
"SetSharedLibraryDirectoryHelper called after "
"ComputeSharedLibraryDirectory");
g_fields->g_shlib_dir_helper = helper;
}
bool HostInfoBase::ComputeSharedLibraryDirectory(
FileSpec &file_spec, SharedLibraryDirectoryHelper *helper) {
// To get paths related to LLDB we get the path to the executable that
// contains this function. On MacOSX this will be "LLDB.framework/.../LLDB".
// On other posix systems, we will get .../lib(64|32)?/liblldb.so.
@ -277,8 +296,8 @@ bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) {
FileSpec lldb_file_spec(Host::GetModuleFileSpecForHostAddress(
reinterpret_cast<void *>(HostInfoBase::ComputeSharedLibraryDirectory)));
if (g_shlib_dir_helper)
g_shlib_dir_helper(lldb_file_spec);
if (helper)
helper(lldb_file_spec);
// Remove the filename so that this FileSpec only represents the directory.
file_spec.SetDirectory(lldb_file_spec.GetDirectory());

View File

@ -35,8 +35,8 @@ struct HostInfoLinuxFields {
static HostInfoLinuxFields *g_fields = nullptr;
void HostInfoLinux::Initialize(SharedLibraryDirectoryHelper *helper) {
HostInfoPosix::Initialize(helper);
void HostInfoLinux::Initialize() {
HostInfoPosix::Initialize();
g_fields = new HostInfoLinuxFields();
}

View File

@ -40,9 +40,9 @@ protected:
FileSpec HostInfoWindows::m_program_filespec;
void HostInfoWindows::Initialize(SharedLibraryDirectoryHelper *helper) {
void HostInfoWindows::Initialize() {
::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
HostInfoBase::Initialize(helper);
HostInfoBase::Initialize();
}
void HostInfoWindows::Terminate() {

View File

@ -35,9 +35,7 @@
using namespace lldb_private;
SystemInitializerCommon::SystemInitializerCommon(
HostInfo::SharedLibraryDirectoryHelper *helper)
: m_shlib_dir_helper(helper) {}
SystemInitializerCommon::SystemInitializerCommon() = default;
SystemInitializerCommon::~SystemInitializerCommon() = default;
@ -68,7 +66,7 @@ llvm::Error SystemInitializerCommon::Initialize() {
Diagnostics::Initialize();
FileSystem::Initialize();
HostInfo::Initialize(m_shlib_dir_helper);
HostInfo::Initialize();
llvm::Error error = Socket::Initialize();
if (error)

View File

@ -290,6 +290,8 @@ llvm::StringRef ScriptInterpreterPython::GetPluginDescriptionStatic() {
}
void ScriptInterpreterPython::Initialize() {
HostInfo::SetSharedLibraryDirectoryHelper(
ScriptInterpreterPython::SharedLibraryDirectoryHelper);
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),

View File

@ -214,7 +214,7 @@ int main(int argc, char *argv[]) {
#endif
if (llvm::Error err = g_debugger_lifetime->Initialize(
std::make_unique<lldb_private::SystemInitializerCommon>(nullptr)))
std::make_unique<lldb_private::SystemInitializerCommon>()))
exitWithError(std::move(err));
llvm::scope_exit cleanup([] { g_debugger_lifetime->Terminate(); });

View File

@ -14,7 +14,7 @@
class SystemInitializerLLGS : public lldb_private::SystemInitializerCommon {
public:
SystemInitializerLLGS() : SystemInitializerCommon(nullptr) {}
SystemInitializerLLGS() : SystemInitializerCommon() {}
llvm::Error Initialize() override;
void Terminate() override;

View File

@ -22,8 +22,7 @@
using namespace lldb_private;
SystemInitializerTest::SystemInitializerTest()
: SystemInitializerCommon(nullptr) {}
SystemInitializerTest::SystemInitializerTest() : SystemInitializerCommon() {}
SystemInitializerTest::~SystemInitializerTest() = default;
llvm::Error SystemInitializerTest::Initialize() {