[Lldb-commits] [lldb] [lldb-dap] subscribe to target events at the broadcaster-manager level (PR #201866)

Charles Zablit via lldb-commits lldb-commits at lists.llvm.org
Fri Jun 5 09:01:50 PDT 2026


https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/201866

>From 64d2d9a3e9f035bc237f77b37c0372714da4bb3e Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Fri, 5 Jun 2026 16:39:11 +0100
Subject: [PATCH] [lldb-dap] subscribe to target events at the
 broadcaster-manager level

---
 .../attach-commands/TestDAP_attachCommands.py |  1 -
 .../TestDAP_launch_extra_launch_commands.py   |  3 +--
 lldb/tools/lldb-dap/DAP.cpp                   | 19 +---------------
 lldb/tools/lldb-dap/DAPSessionManager.cpp     | 22 ++++++++++++++++++-
 lldb/tools/lldb-dap/EventHelper.cpp           |  4 ++--
 5 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/attach-commands/TestDAP_attachCommands.py b/lldb/test/API/tools/lldb-dap/attach-commands/TestDAP_attachCommands.py
index 525783b3785fb..f24a32edbaa7b 100644
--- a/lldb/test/API/tools/lldb-dap/attach-commands/TestDAP_attachCommands.py
+++ b/lldb/test/API/tools/lldb-dap/attach-commands/TestDAP_attachCommands.py
@@ -12,7 +12,6 @@
 class TestDAP_attachCommands(lldbdap_testcase.DAPTestCaseBase):
     SHARED_BUILD_TESTCASE = False
 
-    @skipIfWindows  # Wait for module events fails.
     @skipIfNetBSD  # Hangs on NetBSD as well
     def test_commands(self):
         """
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_extra_launch_commands.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_extra_launch_commands.py
index cc3c4764a5fd7..ad48af6364aba 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_extra_launch_commands.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_extra_launch_commands.py
@@ -2,7 +2,7 @@
 Test lldb-dap launch request.
 """
 
-from lldbsuite.test.decorators import skipIf, skipIfWindows
+from lldbsuite.test.decorators import skipIf
 from lldbsuite.test.lldbtest import line_number
 import lldbdap_testcase
 
@@ -12,7 +12,6 @@ class TestDAP_launch_extra_launch_commands(lldbdap_testcase.DAPTestCaseBase):
     Tests the "launchCommands" with extra launching settings
     """
 
-    @skipIfWindows  # Wait for module events fails.
     # Flakey on 32-bit Arm Linux.
     @skipIf(oslist=["linux"], archs=["arm$"])
     def test(self):
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index cb34c7b2fd1e8..efd10698b9fb8 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -786,24 +786,7 @@ lldb::SBTarget DAP::CreateTarget(lldb::SBError &error) {
   return target;
 }
 
-void DAP::SetTarget(const lldb::SBTarget target) {
-  this->target = target;
-
-  if (target.IsValid()) {
-    // Configure breakpoint event listeners for the target.
-    lldb::SBListener listener = this->debugger.GetListener();
-    listener.StartListeningForEvents(
-        this->target.GetBroadcaster(),
-        lldb::SBTarget::eBroadcastBitBreakpointChanged |
-            lldb::SBTarget::eBroadcastBitModulesLoaded |
-            lldb::SBTarget::eBroadcastBitModulesUnloaded |
-            lldb::SBTarget::eBroadcastBitSymbolsLoaded |
-            lldb::SBTarget::eBroadcastBitSymbolsChanged |
-            lldb::SBTarget::eBroadcastBitNewTargetCreated);
-    listener.StartListeningForEvents(this->broadcaster,
-                                     eBroadcastBitStopEventThread);
-  }
-}
+void DAP::SetTarget(const lldb::SBTarget target) { this->target = target; }
 
 bool DAP::HandleObject(const Message &M) {
   TelemetryDispatcher dispatcher(&debugger);
diff --git a/lldb/tools/lldb-dap/DAPSessionManager.cpp b/lldb/tools/lldb-dap/DAPSessionManager.cpp
index aa1054f86e143..7e0cac638b45b 100644
--- a/lldb/tools/lldb-dap/DAPSessionManager.cpp
+++ b/lldb/tools/lldb-dap/DAPSessionManager.cpp
@@ -119,6 +119,15 @@ DAPSessionManager::GetEventThreadForDebugger(lldb::SBDebugger debugger,
   listener.StartListeningForEventClass(
       debugger, lldb::SBThread::GetBroadcasterClassName(),
       lldb::SBThread::eBroadcastBitStackChanged);
+  // Listen for target events.
+  listener.StartListeningForEventClass(
+      debugger, lldb::SBTarget::GetBroadcasterClassName(),
+      lldb::SBTarget::eBroadcastBitBreakpointChanged |
+          lldb::SBTarget::eBroadcastBitModulesLoaded |
+          lldb::SBTarget::eBroadcastBitModulesUnloaded |
+          lldb::SBTarget::eBroadcastBitSymbolsLoaded |
+          lldb::SBTarget::eBroadcastBitSymbolsChanged |
+          lldb::SBTarget::eBroadcastBitNewTargetCreated);
 
   // Create a new event thread and store it.
   auto new_thread_sp = std::make_shared<ManagedEventThread>(
@@ -137,7 +146,18 @@ DAP *DAPSessionManager::FindDAPForTarget(lldb::SBTarget target) {
     if (dap && dap->target.IsValid() && dap->target == target)
       return dap;
 
-  return nullptr;
+  // Fallback for events that fire before SetTarget binds the target.
+  // Route to the unique DAP for this target's debugger if there is one.
+  const lldb::user_id_t debugger_id = target.GetDebugger().GetID();
+  DAP *unique_dap = nullptr;
+  for (const auto &[loop, dap] : m_active_sessions) {
+    if (!dap || dap->debugger.GetID() != debugger_id)
+      continue;
+    if (unique_dap)
+      return nullptr;
+    unique_dap = dap;
+  }
+  return unique_dap;
 }
 
 void DAPSessionManager::ReleaseExpiredEventThreads() {
diff --git a/lldb/tools/lldb-dap/EventHelper.cpp b/lldb/tools/lldb-dap/EventHelper.cpp
index e9f64d8e72d08..2e0f71d69db65 100644
--- a/lldb/tools/lldb-dap/EventHelper.cpp
+++ b/lldb/tools/lldb-dap/EventHelper.cpp
@@ -475,7 +475,7 @@ static void HandleTargetEvent(const lldb::SBEvent &event, Log &log) {
 
     // NOTE: Both mutexes must be acquired to prevent deadlock when
     // handling `modules_request`, which also requires both locks.
-    lldb::SBMutex api_mutex = dap->GetAPIMutex();
+    lldb::SBMutex api_mutex = target.GetAPIMutex();
     const std::scoped_lock<lldb::SBMutex, std::mutex> guard(api_mutex,
                                                             dap->modules_mutex);
     for (uint32_t i = 0; i < num_modules; ++i) {
@@ -483,7 +483,7 @@ static void HandleTargetEvent(const lldb::SBEvent &event, Log &log) {
           lldb::SBTarget::GetModuleAtIndexFromEvent(i, event);
 
       std::optional<protocol::Module> p_module =
-          CreateModule(dap->target, module, remove_module);
+          CreateModule(target, module, remove_module);
       if (!p_module)
         continue;
 



More information about the lldb-commits mailing list