Skip to content

Conversation

JDevlieghere
Copy link
Member

Currently, the server keeps running until we call Stop from its dtor in the static destruction chain. This is too late: the server should stop when the plugin gets terminated.

Currently, the server keeps running until we call Stop from its dtor in
the static destruction chain. This is too late: the server should stop
when the plugin gets terminated.
@JDevlieghere JDevlieghere requested a review from ashgti August 29, 2025 20:32
@llvmbot llvmbot added the lldb label Aug 29, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 29, 2025

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

Changes

Currently, the server keeps running until we call Stop from its dtor in the static destruction chain. This is too late: the server should stop when the plugin gets terminated.


Full diff: https://github.com/llvm/llvm-project/pull/156101.diff

3 Files Affected:

  • (modified) lldb/include/lldb/Core/ProtocolServer.h (+2)
  • (modified) lldb/source/Core/ProtocolServer.cpp (+27-7)
  • (modified) lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp (+2)
diff --git a/lldb/include/lldb/Core/ProtocolServer.h b/lldb/include/lldb/Core/ProtocolServer.h
index 937256c10aec1..fcb91ea203e10 100644
--- a/lldb/include/lldb/Core/ProtocolServer.h
+++ b/lldb/include/lldb/Core/ProtocolServer.h
@@ -22,6 +22,8 @@ class ProtocolServer : public PluginInterface {
 
   static ProtocolServer *GetOrCreate(llvm::StringRef name);
 
+  static llvm::Error Terminate();
+
   static std::vector<llvm::StringRef> GetSupportedProtocols();
 
   struct Connection {
diff --git a/lldb/source/Core/ProtocolServer.cpp b/lldb/source/Core/ProtocolServer.cpp
index 41636cdacdecc..38668f39795a9 100644
--- a/lldb/source/Core/ProtocolServer.cpp
+++ b/lldb/source/Core/ProtocolServer.cpp
@@ -8,24 +8,29 @@
 
 #include "lldb/Core/ProtocolServer.h"
 #include "lldb/Core/PluginManager.h"
+#include "llvm/Support/Error.h"
 
 using namespace lldb_private;
 using namespace lldb;
 
-ProtocolServer *ProtocolServer::GetOrCreate(llvm::StringRef name) {
-  static std::mutex g_mutex;
+static std::pair<llvm::StringMap<ProtocolServerUP> &, std::mutex &> Servers() {
   static llvm::StringMap<ProtocolServerUP> g_protocol_server_instances;
+  static std::mutex g_mutex;
+  return {g_protocol_server_instances, g_mutex};
+}
+
+ProtocolServer *ProtocolServer::GetOrCreate(llvm::StringRef name) {
+  auto [protocol_server_instances, mutex] = Servers();
 
-  std::lock_guard<std::mutex> guard(g_mutex);
+  std::lock_guard<std::mutex> guard(mutex);
 
-  auto it = g_protocol_server_instances.find(name);
-  if (it != g_protocol_server_instances.end())
+  auto it = protocol_server_instances.find(name);
+  if (it != protocol_server_instances.end())
     return it->second.get();
 
   if (ProtocolServerCreateInstance create_callback =
           PluginManager::GetProtocolCreateCallbackForPluginName(name)) {
-    auto pair =
-        g_protocol_server_instances.try_emplace(name, create_callback());
+    auto pair = protocol_server_instances.try_emplace(name, create_callback());
     return pair.first->second.get();
   }
 
@@ -45,3 +50,18 @@ std::vector<llvm::StringRef> ProtocolServer::GetSupportedProtocols() {
 
   return supported_protocols;
 }
+
+llvm::Error ProtocolServer::Terminate() {
+  llvm::Error error = llvm::Error::success();
+
+  auto [protocol_server_instances, mutex] = Servers();
+  std::lock_guard<std::mutex> guard(mutex);
+  for (auto &instance : protocol_server_instances) {
+    if (llvm::Error instance_error = instance.second->Stop())
+      error = llvm::joinErrors(std::move(error), std::move(instance_error));
+  }
+
+  protocol_server_instances.clear();
+
+  return error;
+}
diff --git a/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp b/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
index 57132534cf680..e6c5d9bc9c278 100644
--- a/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
+++ b/lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp
@@ -39,6 +39,8 @@ void ProtocolServerMCP::Initialize() {
 }
 
 void ProtocolServerMCP::Terminate() {
+  if (llvm::Error error = ProtocolServer::Terminate())
+    LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(error), "{0}");
   PluginManager::UnregisterPlugin(CreateInstance);
 }
 

@JDevlieghere
Copy link
Member Author

This is the cause of the test failure in #155714. This behavior will be covered by John's new test.

Copy link
Contributor

@ashgti ashgti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@JDevlieghere JDevlieghere merged commit df4c367 into llvm:main Aug 29, 2025
11 checks passed
@JDevlieghere JDevlieghere deleted the terminate-mcp-server branch August 29, 2025 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants