Author: Jonas Devlieghere
Date: 2025-04-27T10:21:19-07:00
New Revision: b546baff48767d54da03049d4f30690649a5e599

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

LOG: [lldb-dap] Support the Module Event (#137380)

The module event indicates that some information about a module has
changed. The event is supported by the Emacs and Visual Studio DAP
clients. This PR adds support for emitting the event from lldb-dap.

Fixes #137058

Added: 
    

Modified: 
    lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
    lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
    lldb/tools/lldb-dap/DAP.cpp
    lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 40bdcf99e5b09..99fcc423894b6 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -135,6 +135,7 @@ def __init__(self, recv, send, init_commands, 
log_file=None):
         self.breakpoint_events = []
         self.progress_events = []
         self.reverse_requests = []
+        self.module_events = []
         self.sequence = 1
         self.threads = None
         self.recv_thread.start()
@@ -255,6 +256,11 @@ def handle_recv_packet(self, packet):
                 # and 'progressEnd' events. Keep these around in case test
                 # cases want to verify them.
                 self.progress_events.append(packet)
+            elif event == "module":
+                # Module events indicate that some information about a module 
has changed.
+                self.module_events.append(packet)
+                # no need to add 'module' event packets to our packets list
+                return keepGoing
 
         elif packet_type == "response":
             if packet["command"] == "disconnect":

diff  --git a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py 
b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
index a4e0f04d450d9..210819cfdd732 100644
--- a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
+++ b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
@@ -57,6 +57,27 @@ def checkSymbolsLoadedWithSize():
         self.assertEqual(program, program_module["path"])
         self.assertIn("addressRange", program_module)
 
+        # Collect all the module names we saw as events.
+        module_new_names = []
+        module_changed_names = []
+        for module_event in self.dap_server.module_events:
+            module_name = module_event["body"]["module"]["name"]
+            reason = module_event["body"]["reason"]
+            if reason == "new":
+                module_new_names.append(module_name)
+            elif reason == "changed":
+                module_changed_names.append(module_name)
+
+        # Make sure we got an event for every active module.
+        self.assertNotEqual(len(module_new_names), 0)
+        for module in active_modules:
+            self.assertIn(module, module_new_names)
+
+        # Make sure we got an update event for the program module when the
+        # symbols got added.
+        self.assertNotEqual(len(module_changed_names), 0)
+        self.assertIn(program_module["name"], module_changed_names)
+
     @skipIfWindows
     def test_modules(self):
         """

diff  --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 55d49667b6398..b593353110787 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -693,7 +693,11 @@ void DAP::SetTarget(const lldb::SBTarget target) {
     lldb::SBListener listener = this->debugger.GetListener();
     listener.StartListeningForEvents(
         this->target.GetBroadcaster(),
-        lldb::SBTarget::eBroadcastBitBreakpointChanged);
+        lldb::SBTarget::eBroadcastBitBreakpointChanged |
+            lldb::SBTarget::eBroadcastBitModulesLoaded |
+            lldb::SBTarget::eBroadcastBitModulesUnloaded |
+            lldb::SBTarget::eBroadcastBitSymbolsLoaded |
+            lldb::SBTarget::eBroadcastBitSymbolsChanged);
     listener.StartListeningForEvents(this->broadcaster,
                                      eBroadcastBitStopEventThread);
   }

diff  --git a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp 
b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
index 7d8ac676ba935..ce34c52bcc334 100644
--- a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
@@ -15,6 +15,8 @@
 #include "lldb/API/SBEvent.h"
 #include "lldb/API/SBListener.h"
 #include "lldb/API/SBStream.h"
+#include "lldb/API/SBTarget.h"
+#include <cstdint>
 
 using namespace lldb;
 using namespace lldb_dap::protocol;
@@ -108,6 +110,16 @@ void ProgressEventThreadFunction(DAP &dap) {
   }
 }
 
+static llvm::StringRef GetModuleEventReason(uint32_t event_mask) {
+  if (event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded)
+    return "new";
+  if (event_mask & lldb::SBTarget::eBroadcastBitModulesUnloaded)
+    return "removed";
+  assert(event_mask & lldb::SBTarget::eBroadcastBitSymbolsLoaded ||
+         event_mask & lldb::SBTarget::eBroadcastBitSymbolsChanged);
+  return "changed";
+}
+
 // All events from the debugger, target, process, thread and frames are
 // received in this function that runs in its own thread. We are using a
 // "FILE *" to output packets back to VS Code and they have mutexes in them
@@ -193,6 +205,27 @@ static void EventThreadFunction(DAP &dap) {
                    (event_mask & lldb::SBProcess::eBroadcastBitSTDERR)) {
           SendStdOutStdErr(dap, process);
         }
+      } else if (lldb::SBTarget::EventIsTargetEvent(event)) {
+        if (event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded ||
+            event_mask & lldb::SBTarget::eBroadcastBitModulesUnloaded ||
+            event_mask & lldb::SBTarget::eBroadcastBitSymbolsLoaded ||
+            event_mask & lldb::SBTarget::eBroadcastBitSymbolsChanged) {
+          llvm::StringRef reason = GetModuleEventReason(event_mask);
+          const uint32_t num_modules = SBTarget::GetNumModulesFromEvent(event);
+          for (uint32_t i = 0; i < num_modules; ++i) {
+            lldb::SBModule module =
+                SBTarget::GetModuleAtIndexFromEvent(i, event);
+            if (!module.IsValid())
+              continue;
+
+            llvm::json::Object body;
+            body.try_emplace("reason", reason);
+            body.try_emplace("module", CreateModule(dap.target, module));
+            llvm::json::Object module_event = CreateEventObject("module");
+            module_event.try_emplace("body", std::move(body));
+            dap.SendJSON(llvm::json::Value(std::move(module_event)));
+          }
+        }
       } else if (lldb::SBBreakpoint::EventIsBreakpointEvent(event)) {
         if (event_mask & lldb::SBTarget::eBroadcastBitBreakpointChanged) {
           auto event_type =


        
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to