From 329c52c1004f2d0f487577f73387c8dd8b47fd9a Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 27 Feb 2026 15:27:02 -0800 Subject: [PATCH] [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. --- lldb/include/lldb/Host/HostInfoBase.h | 8 +++-- lldb/include/lldb/Host/aix/HostInfoAIX.h | 2 +- lldb/include/lldb/Host/linux/HostInfoLinux.h | 2 +- .../lldb/Host/windows/HostInfoWindows.h | 2 +- .../Initialization/SystemInitializerCommon.h | 5 +-- lldb/source/API/SystemInitializerFull.cpp | 15 +------- lldb/source/Host/aix/HostInfoAIX.cpp | 4 +-- lldb/source/Host/common/HostInfoBase.cpp | 35 ++++++++++++++----- lldb/source/Host/linux/HostInfoLinux.cpp | 4 +-- lldb/source/Host/windows/HostInfoWindows.cpp | 4 +-- .../SystemInitializerCommon.cpp | 6 ++-- .../Python/ScriptInterpreterPython.cpp | 2 ++ lldb/tools/lldb-mcp/lldb-mcp.cpp | 2 +- .../tools/lldb-server/SystemInitializerLLGS.h | 2 +- .../tools/lldb-test/SystemInitializerTest.cpp | 3 +- 15 files changed, 50 insertions(+), 46 deletions(-) diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index cfc41581636b..3074a97a6fac 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -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); diff --git a/lldb/include/lldb/Host/aix/HostInfoAIX.h b/lldb/include/lldb/Host/aix/HostInfoAIX.h index 7796a1523780..a88d9f66162a 100644 --- a/lldb/include/lldb/Host/aix/HostInfoAIX.h +++ b/lldb/include/lldb/Host/aix/HostInfoAIX.h @@ -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(); diff --git a/lldb/include/lldb/Host/linux/HostInfoLinux.h b/lldb/include/lldb/Host/linux/HostInfoLinux.h index 904d679e6d95..0270cbcefcd5 100644 --- a/lldb/include/lldb/Host/linux/HostInfoLinux.h +++ b/lldb/include/lldb/Host/linux/HostInfoLinux.h @@ -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(); diff --git a/lldb/include/lldb/Host/windows/HostInfoWindows.h b/lldb/include/lldb/Host/windows/HostInfoWindows.h index 8a4f5c7cb84d..42eaaf3415f7 100644 --- a/lldb/include/lldb/Host/windows/HostInfoWindows.h +++ b/lldb/include/lldb/Host/windows/HostInfoWindows.h @@ -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(); diff --git a/lldb/include/lldb/Initialization/SystemInitializerCommon.h b/lldb/include/lldb/Initialization/SystemInitializerCommon.h index d918b1125a57..6884e4664f69 100644 --- a/lldb/include/lldb/Initialization/SystemInitializerCommon.h +++ b/lldb/include/lldb/Initialization/SystemInitializerCommon.h @@ -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 diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index 4cf7dd149e02..d994915913cc 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -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() { diff --git a/lldb/source/Host/aix/HostInfoAIX.cpp b/lldb/source/Host/aix/HostInfoAIX.cpp index aab3bf62a635..5ad9e61297f0 100644 --- a/lldb/source/Host/aix/HostInfoAIX.cpp +++ b/lldb/source/Host/aix/HostInfoAIX.cpp @@ -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(); } diff --git a/lldb/source/Host/common/HostInfoBase.cpp b/lldb/source/Host/common/HostInfoBase.cpp index a02ac77df66a..bbc60ef187c8 100644 --- a/lldb/source/Host/common/HostInfoBase.cpp +++ b/lldb/source/Host/common/HostInfoBase.cpp @@ -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(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()); diff --git a/lldb/source/Host/linux/HostInfoLinux.cpp b/lldb/source/Host/linux/HostInfoLinux.cpp index 711d2ca6f13d..bb929f18505e 100644 --- a/lldb/source/Host/linux/HostInfoLinux.cpp +++ b/lldb/source/Host/linux/HostInfoLinux.cpp @@ -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(); } diff --git a/lldb/source/Host/windows/HostInfoWindows.cpp b/lldb/source/Host/windows/HostInfoWindows.cpp index bdb234c07859..0b0cda49a64c 100644 --- a/lldb/source/Host/windows/HostInfoWindows.cpp +++ b/lldb/source/Host/windows/HostInfoWindows.cpp @@ -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() { diff --git a/lldb/source/Initialization/SystemInitializerCommon.cpp b/lldb/source/Initialization/SystemInitializerCommon.cpp index 1a172a95aa14..4ff9354e0d45 100644 --- a/lldb/source/Initialization/SystemInitializerCommon.cpp +++ b/lldb/source/Initialization/SystemInitializerCommon.cpp @@ -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) diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 1c82ba0accb1..e1a4bea47c9a 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -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(), diff --git a/lldb/tools/lldb-mcp/lldb-mcp.cpp b/lldb/tools/lldb-mcp/lldb-mcp.cpp index d0c44b2cf41f..6a534dc8e320 100644 --- a/lldb/tools/lldb-mcp/lldb-mcp.cpp +++ b/lldb/tools/lldb-mcp/lldb-mcp.cpp @@ -214,7 +214,7 @@ int main(int argc, char *argv[]) { #endif if (llvm::Error err = g_debugger_lifetime->Initialize( - std::make_unique(nullptr))) + std::make_unique())) exitWithError(std::move(err)); llvm::scope_exit cleanup([] { g_debugger_lifetime->Terminate(); }); diff --git a/lldb/tools/lldb-server/SystemInitializerLLGS.h b/lldb/tools/lldb-server/SystemInitializerLLGS.h index 4469a8ba5f60..24cf400a67f9 100644 --- a/lldb/tools/lldb-server/SystemInitializerLLGS.h +++ b/lldb/tools/lldb-server/SystemInitializerLLGS.h @@ -14,7 +14,7 @@ class SystemInitializerLLGS : public lldb_private::SystemInitializerCommon { public: - SystemInitializerLLGS() : SystemInitializerCommon(nullptr) {} + SystemInitializerLLGS() : SystemInitializerCommon() {} llvm::Error Initialize() override; void Terminate() override; diff --git a/lldb/tools/lldb-test/SystemInitializerTest.cpp b/lldb/tools/lldb-test/SystemInitializerTest.cpp index 3478e5d8df99..10e80c6fee49 100644 --- a/lldb/tools/lldb-test/SystemInitializerTest.cpp +++ b/lldb/tools/lldb-test/SystemInitializerTest.cpp @@ -22,8 +22,7 @@ using namespace lldb_private; -SystemInitializerTest::SystemInitializerTest() - : SystemInitializerCommon(nullptr) {} +SystemInitializerTest::SystemInitializerTest() : SystemInitializerCommon() {} SystemInitializerTest::~SystemInitializerTest() = default; llvm::Error SystemInitializerTest::Initialize() {