Author: Charles Zablit
Date: 2026-06-17T14:22:48+01:00
New Revision: c10d23a190ca64fe3d93c7e22989ff1d3f5f918a

URL: 
https://github.com/llvm/llvm-project/commit/c10d23a190ca64fe3d93c7e22989ff1d3f5f918a
DIFF: 
https://github.com/llvm/llvm-project/commit/c10d23a190ca64fe3d93c7e22989ff1d3f5f918a.diff

LOG: [lldb-dap] subscribe to target events at the broadcaster-manager level 
(#201866)

https://github.com/llvm/llvm-project/pull/200133 added
`wait_for_module_events()` assertions to `TestDAP_attachCommands.py` and
`TestDAP_launch_extra_launch_commands.py`. However, `SetTarget` is
called after the `Run*Commands`, so this fails on Windows, because it
loads modules early during the process startup. The module-load events
are not listened to.

This patch moves the event subscription to
`DAPSessionManager::GetEventThreadForDebugger` and uses
`StartListeningForEventClass` so any target created in this debugger
automatically gets the listener attached. This is the same pattern we
already use for `SBThread` events.

This is a follow up to https://github.com/llvm/llvm-project/pull/201796
which skipped the tests.

rdar://179923440

Added: 
    

Modified: 
    lldb/test/API/tools/lldb-dap/attach-commands/TestDAP_attachCommands.py
    lldb/test/API/tools/lldb-dap/launch/TestDAP_launch_extra_launch_commands.py
    lldb/tools/lldb-dap/DAP.cpp
    lldb/tools/lldb-dap/DAPSessionManager.cpp
    lldb/tools/lldb-dap/EventHelper.cpp

Removed: 
    


################################################################################
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..580d4fa102a89 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>(
@@ -133,10 +142,10 @@ 
DAPSessionManager::GetEventThreadForDebugger(lldb::SBDebugger debugger,
 DAP *DAPSessionManager::FindDAPForTarget(lldb::SBTarget target) {
   std::lock_guard<std::mutex> lock(m_sessions_mutex);
 
+  const lldb::user_id_t debugger_id = target.GetDebugger().GetID();
   for (const auto &[loop, dap] : m_active_sessions)
-    if (dap && dap->target.IsValid() && dap->target == target)
+    if (dap && dap->debugger.GetID() == debugger_id)
       return dap;
-
   return nullptr;
 }
 

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;
 


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to