[Lldb-commits] [lldb] [lldb] Assert & fix missing calls to UnregisterPlugin (PR #185162)

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Sat Mar 7 11:18:57 PST 2026


https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/185162

>From 9a957087f6a90b80c5e5f7b9e80d9839d017d6f7 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Fri, 6 Mar 2026 23:37:20 -0800
Subject: [PATCH 1/3] [lldb] Assert & fix missing calls to UnregisterPlugin

Fix missing calls to UnregisterPlugin and add an assert in the
PluginManager that ensures all plugins have been unregistered by the
time the plugin manager is destroyed.
---
 lldb/source/Core/PluginManager.cpp                           | 4 ++++
 .../DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp  | 4 +++-
 .../DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp      | 4 +++-
 .../DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp  | 4 +++-
 .../DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp        | 4 ++++
 .../Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h  | 2 +-
 lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp       | 4 ----
 lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp       | 2 +-
 lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.cpp | 4 ----
 .../source/Plugins/Process/Windows/Common/ProcessWindows.cpp | 5 ++++-
 .../Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp | 4 +++-
 .../Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp   | 4 +++-
 .../Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp | 4 +++-
 .../ScriptInterpreter/Python/ScriptInterpreterPython.cpp     | 1 +
 lldb/tools/lldb-test/SystemInitializerTest.cpp               | 2 +-
 lldb/unittests/Process/ProcessTraceTest.cpp                  | 2 +-
 lldb/unittests/Target/LocateModuleCallbackTest.cpp           | 3 +++
 17 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index 7e2b6db5a5221..55fd14e12ae59 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -493,6 +493,10 @@ template <typename Callback> struct PluginInstance {
 
 template <typename Instance> class PluginInstances {
 public:
+  ~PluginInstances() {
+    assert(m_instances.empty() && "forgot to unregister plugin?");
+  }
+
   template <typename... Args>
   bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
                       typename Instance::CallbackType callback,
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
index fe9572296a913..66860f829add3 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
@@ -77,7 +77,9 @@ void DynamicLoaderHexagonDYLD::Initialize() {
                                 GetPluginDescriptionStatic(), CreateInstance);
 }
 
-void DynamicLoaderHexagonDYLD::Terminate() {}
+void DynamicLoaderHexagonDYLD::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
 
 llvm::StringRef DynamicLoaderHexagonDYLD::GetPluginDescriptionStatic() {
   return "Dynamic loader plug-in that watches for shared library "
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 3541d2f998c45..5e7c44d796bb9 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -42,7 +42,9 @@ void DynamicLoaderPOSIXDYLD::Initialize() {
                                 GetPluginDescriptionStatic(), CreateInstance);
 }
 
-void DynamicLoaderPOSIXDYLD::Terminate() {}
+void DynamicLoaderPOSIXDYLD::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
 
 llvm::StringRef DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() {
   return "Dynamic loader plug-in that watches for shared library "
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index 348cf58d69243..44d671f843b74 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -36,7 +36,9 @@ void DynamicLoaderWindowsDYLD::Initialize() {
                                 GetPluginDescriptionStatic(), CreateInstance);
 }
 
-void DynamicLoaderWindowsDYLD::Terminate() {}
+void DynamicLoaderWindowsDYLD::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
 
 llvm::StringRef DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() {
   return "Dynamic loader plug-in that watches for shared library "
diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
index 2aed7c9e00dc4..69e41ac5ebd12 100644
--- a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
@@ -31,6 +31,10 @@ void DynamicLoaderWasmDYLD::Initialize() {
                                 GetPluginDescriptionStatic(), CreateInstance);
 }
 
+void DynamicLoaderWasmDYLD::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
+
 llvm::StringRef DynamicLoaderWasmDYLD::GetPluginDescriptionStatic() {
   return "Dynamic loader plug-in that watches for shared library "
          "loads/unloads in WebAssembly engines.";
diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
index 07b3f9673a9c5..8bcbc64bdc433 100644
--- a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
@@ -19,7 +19,7 @@ class DynamicLoaderWasmDYLD : public DynamicLoader {
   DynamicLoaderWasmDYLD(Process *process);
 
   static void Initialize();
-  static void Terminate() {}
+  static void Terminate();
 
   static llvm::StringRef GetPluginNameStatic() { return "wasm-dyld"; }
   static llvm::StringRef GetPluginDescriptionStatic();
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 2c5b10c07ee26..bfe85899690ab 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -90,8 +90,6 @@ PlatformDarwin::~PlatformDarwin() = default;
 static uint32_t g_initialize_count = 0;
 
 void PlatformDarwin::Initialize() {
-  Platform::Initialize();
-
   if (g_initialize_count++ == 0) {
     PluginManager::RegisterPlugin(PlatformDarwin::GetPluginNameStatic(),
                                   PlatformDarwin::GetDescriptionStatic(),
@@ -106,8 +104,6 @@ void PlatformDarwin::Terminate() {
       PluginManager::UnregisterPlugin(PlatformDarwin::CreateInstance);
     }
   }
-
-  Platform::Terminate();
 }
 
 llvm::StringRef PlatformDarwin::GetDescriptionStatic() {
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
index bf653cd758295..62a696052e05d 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -84,7 +84,7 @@ void PlatformMacOSX::Terminate() {
   PlatformDarwinKernel::Terminate();
   PlatformAppleSimulator::Terminate();
 #endif
-  PlatformRemoteMacOSX::Initialize();
+  PlatformRemoteMacOSX::Terminate();
   PlatformRemoteiOS::Terminate();
   PlatformDarwin::Terminate();
 }
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.cpp
index 460f6d8bd6170..21bb0c51ef31e 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteMacOSX.cpp
@@ -38,8 +38,6 @@ static uint32_t g_initialize_count = 0;
 
 // Static Functions
 void PlatformRemoteMacOSX::Initialize() {
-  PlatformDarwin::Initialize();
-
   if (g_initialize_count++ == 0) {
     PluginManager::RegisterPlugin(PlatformRemoteMacOSX::GetPluginNameStatic(),
                                   PlatformRemoteMacOSX::GetDescriptionStatic(),
@@ -53,8 +51,6 @@ void PlatformRemoteMacOSX::Terminate() {
       PluginManager::UnregisterPlugin(PlatformRemoteMacOSX::CreateInstance);
     }
   }
-
-  PlatformDarwin::Terminate();
 }
 
 PlatformSP PlatformRemoteMacOSX::CreateInstance(bool force,
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index c61a41cd00444..7259bc2aa2382 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -107,7 +107,10 @@ void ProcessWindows::Initialize() {
   }
 }
 
-void ProcessWindows::Terminate() {}
+void ProcessWindows::Terminate() {
+  if (!ShouldUseLLDBServer())
+    PluginManager::UnregisterPlugin(CreateInstance);
+}
 
 llvm::StringRef ProcessWindows::GetPluginDescriptionStatic() {
   return "Process plugin for Windows";
diff --git a/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp b/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp
index 92dfb56004987..80d5289178ed0 100644
--- a/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp
+++ b/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp
@@ -23,7 +23,9 @@ void RegisterTypeBuilderClang::Initialize() {
                                 GetPluginDescriptionStatic(), CreateInstance);
 }
 
-void RegisterTypeBuilderClang::Terminate() {}
+void RegisterTypeBuilderClang::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
 
 lldb::RegisterTypeBuilderSP
 RegisterTypeBuilderClang::CreateInstance(Target &target) {
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
index 8ec1dc6799b98..00b580bb0474f 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -245,7 +245,9 @@ void ScriptInterpreterLua::Initialize() {
                                 lldb::eScriptLanguageLua, CreateInstance);
 }
 
-void ScriptInterpreterLua::Terminate() {}
+void ScriptInterpreterLua::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
 
 llvm::Error ScriptInterpreterLua::EnterSession(user_id_t debugger_id) {
   if (m_session_is_active)
diff --git a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
index 4a93ca309f50e..1e4b6f4c21477 100644
--- a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
@@ -43,7 +43,9 @@ void ScriptInterpreterNone::Initialize() {
                                 lldb::eScriptLanguageNone, CreateInstance);
 }
 
-void ScriptInterpreterNone::Terminate() {}
+void ScriptInterpreterNone::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
 
 lldb::ScriptInterpreterSP
 ScriptInterpreterNone::CreateInstance(Debugger &debugger) {
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 24228a62708fd..de8be43aa35fd 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -301,6 +301,7 @@ void ScriptInterpreterPython::Initialize() {
 
 void ScriptInterpreterPython::Terminate() {
   ScriptInterpreterPythonInterfaces::Terminate();
+  PluginManager::UnregisterPlugin(ScriptInterpreterPythonImpl::CreateInstance);
 }
 
 ScriptInterpreterPythonImpl::Locker::Locker(
diff --git a/lldb/tools/lldb-test/SystemInitializerTest.cpp b/lldb/tools/lldb-test/SystemInitializerTest.cpp
index 10e80c6fee499..03c32553c87e7 100644
--- a/lldb/tools/lldb-test/SystemInitializerTest.cpp
+++ b/lldb/tools/lldb-test/SystemInitializerTest.cpp
@@ -69,7 +69,7 @@ void SystemInitializerTest::Terminate() {
 
   // We ignored all the script interpreter earlier, so terminate
   // ScriptInterpreterNone explicitly.
-  LLDB_PLUGIN_INITIALIZE(ScriptInterpreterNone);
+  LLDB_PLUGIN_TERMINATE(ScriptInterpreterNone);
 
   // Now shutdown the common parts, in reverse order.
   SystemInitializerCommon::Terminate();
diff --git a/lldb/unittests/Process/ProcessTraceTest.cpp b/lldb/unittests/Process/ProcessTraceTest.cpp
index fc6b92e868248..0bf7ddcbbda21 100644
--- a/lldb/unittests/Process/ProcessTraceTest.cpp
+++ b/lldb/unittests/Process/ProcessTraceTest.cpp
@@ -26,7 +26,7 @@ class ProcessTraceTest : public ::testing::Test {
     PlatformLinux::Initialize();
   }
   void TearDown() override {
-    PlatformLinux::Initialize();
+    PlatformLinux::Terminate();
     HostInfo::Terminate();
     FileSystem::Terminate();
     ProcessTrace::Terminate();
diff --git a/lldb/unittests/Target/LocateModuleCallbackTest.cpp b/lldb/unittests/Target/LocateModuleCallbackTest.cpp
index f5792e6ce4890..94c082b344262 100644
--- a/lldb/unittests/Target/LocateModuleCallbackTest.cpp
+++ b/lldb/unittests/Target/LocateModuleCallbackTest.cpp
@@ -224,6 +224,9 @@ class LocateModuleCallbackTest : public testing::Test {
     // Create MockProcess.
     PluginManager::RegisterPlugin(k_process_plugin, "",
                                   MockProcessCreateInstance);
+    auto unregister_plugin = llvm::scope_exit(
+        [&]() { PluginManager::UnregisterPlugin(MockProcessCreateInstance); });
+
     m_process_sp =
         m_target_sp->CreateProcess(Listener::MakeListener("test-listener"),
                                    k_process_plugin, /*crash_file=*/nullptr,

>From 3014ecc0260b8290e4182290ad60a38f2bb6f2ad Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Sat, 7 Mar 2026 10:58:23 -0800
Subject: [PATCH 2/3] Add missing Terminate calls to tests

---
 lldb/test/API/api/command-return-object/main.cpp    | 1 +
 lldb/test/API/api/multithreaded/driver.cpp.template | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lldb/test/API/api/command-return-object/main.cpp b/lldb/test/API/api/command-return-object/main.cpp
index c1d4d246a43c8..690362a9a6da3 100644
--- a/lldb/test/API/api/command-return-object/main.cpp
+++ b/lldb/test/API/api/command-return-object/main.cpp
@@ -30,4 +30,5 @@ int main() {
   interp.AddCommand("crasher", &crasher, nullptr /*help*/);
   SBCommandReturnObject Result;
   dbg.GetCommandInterpreter().HandleCommand("crasher", Result);
+  SBDebugger::Terminate();
 }
diff --git a/lldb/test/API/api/multithreaded/driver.cpp.template b/lldb/test/API/api/multithreaded/driver.cpp.template
index 32459425c88c3..443f4fed7653d 100644
--- a/lldb/test/API/api/multithreaded/driver.cpp.template
+++ b/lldb/test/API/api/multithreaded/driver.cpp.template
@@ -47,5 +47,6 @@ int main(int argc, char** argv) {
   }
 
   SBDebugger::Destroy(dbg);
+  SBDebugger::Terminate();
   return code;
 }

>From 113c5062bca24c0ae8276dd9aa33e2d1a59a9301 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Sat, 7 Mar 2026 11:18:44 -0800
Subject: [PATCH 3/3] Add another missing unregisterplugin in
 PlatformDarwinTest

---
 lldb/unittests/Platform/PlatformDarwinTest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/unittests/Platform/PlatformDarwinTest.cpp b/lldb/unittests/Platform/PlatformDarwinTest.cpp
index 5947ea6428f54..8fac4b7650e13 100644
--- a/lldb/unittests/Platform/PlatformDarwinTest.cpp
+++ b/lldb/unittests/Platform/PlatformDarwinTest.cpp
@@ -49,7 +49,7 @@ class MockScriptInterpreterPython : public ScriptInterpreter {
                                   lldb::eScriptLanguagePython, CreateInstance);
   }
 
-  static void Terminate() {}
+  static void Terminate() { PluginManager::UnregisterPlugin(CreateInstance); }
 
   static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger) {
     return std::make_shared<MockScriptInterpreterPython>(debugger);



More information about the lldb-commits mailing list