Skip to content

[lldb-dap] Simplify DAPSessionManager GetInstance#209264

Merged
da-viper merged 3 commits into
llvm:mainfrom
da-viper:fix-data-race-dap_session_manager
Jul 14, 2026
Merged

[lldb-dap] Simplify DAPSessionManager GetInstance#209264
da-viper merged 3 commits into
llvm:mainfrom
da-viper:fix-data-race-dap_session_manager

Conversation

@da-viper

Copy link
Copy Markdown
Contributor

We don't need the std::call_once as this guaranteed to be thread safe and initialised once since c++11.
I also don't see any issue with the destructor chain since the class doesn't own any data that can be affected.

We don't need the `std::call_once` as this guaranteed to be
thread safe and initialized once.
I also don't see any issue with the destructor chain since the class
doesn't own any data that can be affected.
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-lldb

Author: Ebuka Ezike (da-viper)

Changes

We don't need the std::call_once as this guaranteed to be thread safe and initialised once since c++11.
I also don't see any issue with the destructor chain since the class doesn't own any data that can be affected.


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

1 Files Affected:

  • (modified) lldb/tools/lldb-dap/DAPSessionManager.cpp (+2-8)
diff --git a/lldb/tools/lldb-dap/DAPSessionManager.cpp b/lldb/tools/lldb-dap/DAPSessionManager.cpp
index 580d4fa102a89..91c0538e63d5f 100644
--- a/lldb/tools/lldb-dap/DAPSessionManager.cpp
+++ b/lldb/tools/lldb-dap/DAPSessionManager.cpp
@@ -33,14 +33,8 @@ ManagedEventThread::~ManagedEventThread() {
 }
 
 DAPSessionManager &DAPSessionManager::GetInstance() {
-  static std::once_flag initialized;
-  static DAPSessionManager *instance =
-      nullptr; // NOTE: intentional leak to avoid issues with C++ destructor
-               // chain
-
-  std::call_once(initialized, []() { instance = new DAPSessionManager(); });
-
-  return *instance;
+  static DAPSessionManager instance;
+  return instance;
 }
 
 void DAPSessionManager::RegisterSession(lldb_private::MainLoop *loop,

@JDevlieghere JDevlieghere left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Dropping call_once is fine, the statics handles thread-safe init. But this also drops the intentional leak which I think was load bearing.

Now the destructor will run at program exit. Client sessions run on detached threads and UnregisterSession ends with notify_all_at_thread_exit. The main thread only waits for the sessions map to empty, which happens before the detached thread finishes its exit tail. So there's a window where ~DAPSessionManager tears down m_sessions_mutex/m_sessions_condition while a detached thread is still notifying them. That's what the old comment was about.

Let's keep the leak but drop the call_once:

DAPSessionManager &DAPSessionManager::GetInstance() {
  // Intentionally leaked: detached client threads may still be notifying on
  // m_sessions_condition at exit, so it has to outlive them.
  static DAPSessionManager *instance = new DAPSessionManager();
  return *instance;
}

@da-viper da-viper requested a review from JDevlieghere July 14, 2026 08:31
@da-viper da-viper merged commit 7cd1a83 into llvm:main Jul 14, 2026
11 checks passed
@da-viper da-viper deleted the fix-data-race-dap_session_manager branch July 14, 2026 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants