[Lldb-commits] [lldb] [lldb-dap] Support the Module Event (PR #137380)
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Fri Apr 25 20:56:36 PDT 2025
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/137380
>From 681beb0f851d20896456b53c51b8ee84382a1254 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Fri, 25 Apr 2025 10:40:45 -0700
Subject: [PATCH 1/2] [lldb-dap] Support the Module Event
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
---
.../test/tools/lldb-dap/dap_server.py | 6 +++++
.../tools/lldb-dap/module/TestDAP_module.py | 11 +++++++++
lldb/tools/lldb-dap/DAP.cpp | 4 +++-
.../Handler/InitializeRequestHandler.cpp | 24 +++++++++++++++++++
4 files changed, 44 insertions(+), 1 deletion(-)
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 0f8a84461c9e7..5c43c91734b43 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..e839d46e1d114 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,17 @@ def checkSymbolsLoadedWithSize():
self.assertEqual(program, program_module["path"])
self.assertIn("addressRange", program_module)
+ # Collect all the module names we saw as events.
+ module_event_names = set()
+ for module_event in self.dap_server.module_events:
+ module_event_names.add(module_event["body"]["module"]["name"])
+ self.assertNotEqual(len(module_event_names), 0)
+
+ # Make sure we got an event for every active module.
+ for module in active_modules:
+ # assertIn doesn't work with set.
+ self.assertTrue(module in module_event_names)
+
@skipIfWindows
def test_modules(self):
"""
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index f8dbc4c1398e6..f866886c33014 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -692,7 +692,9 @@ 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);
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..f98c4d743b2d8 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;
@@ -193,6 +195,28 @@ 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) {
+ const llvm::StringRef reason =
+ event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded
+ ? "new"
+ : "removed";
+ 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 =
>From 47b5695312f540cfd2e1facd397cfd1ffa7889a7 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Fri, 25 Apr 2025 12:05:11 -0700
Subject: [PATCH 2/2] Support changed event too
---
.../tools/lldb-dap/module/TestDAP_module.py | 20 ++++++++++++++-----
lldb/tools/lldb-dap/DAP.cpp | 4 +++-
.../Handler/InitializeRequestHandler.cpp | 19 +++++++++++++-----
3 files changed, 32 insertions(+), 11 deletions(-)
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 e839d46e1d114..210819cfdd732 100644
--- a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
+++ b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py
@@ -58,15 +58,25 @@ def checkSymbolsLoadedWithSize():
self.assertIn("addressRange", program_module)
# Collect all the module names we saw as events.
- module_event_names = set()
+ module_new_names = []
+ module_changed_names = []
for module_event in self.dap_server.module_events:
- module_event_names.add(module_event["body"]["module"]["name"])
- self.assertNotEqual(len(module_event_names), 0)
+ 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:
- # assertIn doesn't work with set.
- self.assertTrue(module in module_event_names)
+ 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 f866886c33014..23198acb8e7cd 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -694,7 +694,9 @@ void DAP::SetTarget(const lldb::SBTarget target) {
this->target.GetBroadcaster(),
lldb::SBTarget::eBroadcastBitBreakpointChanged |
lldb::SBTarget::eBroadcastBitModulesLoaded |
- lldb::SBTarget::eBroadcastBitModulesUnloaded);
+ 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 f98c4d743b2d8..ce34c52bcc334 100644
--- a/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp
@@ -110,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
@@ -197,11 +207,10 @@ static void EventThreadFunction(DAP &dap) {
}
} else if (lldb::SBTarget::EventIsTargetEvent(event)) {
if (event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded ||
- event_mask & lldb::SBTarget::eBroadcastBitModulesUnloaded) {
- const llvm::StringRef reason =
- event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded
- ? "new"
- : "removed";
+ 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 =
More information about the lldb-commits
mailing list