Skip to content

Commit fe72e05

Browse files
committed
[lldb-dap] Support the Module Event (llvm#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 llvm#137058 Back-ported from commit b546baf
1 parent e2ad9dc commit fe72e05

File tree

4 files changed

+63
-2
lines changed

4 files changed

+63
-2
lines changed

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ def __init__(self, recv, send, init_commands, log_file=None):
127127
self.breakpoint_events = []
128128
self.progress_events = []
129129
self.reverse_requests = []
130+
self.module_events = []
130131
self.sequence = 1
131132
self.threads = None
132133
self.recv_thread.start()
@@ -247,7 +248,10 @@ def handle_recv_packet(self, packet):
247248
# and 'progressEnd' events. Keep these around in case test
248249
# cases want to verify them.
249250
self.progress_events.append(packet)
250-
# No need to add 'progress' event packets to our packets list.
251+
elif event == "module":
252+
# Module events indicate that some information about a module has changed.
253+
self.module_events.append(packet)
254+
# no need to add 'module' event packets to our packets list
251255
return keepGoing
252256

253257
elif packet_type == "response":

lldb/test/API/tools/lldb-dap/module/TestDAP_module.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,27 @@ def checkSymbolsLoadedWithSize():
5757
self.assertEqual(program, program_module["path"])
5858
self.assertIn("addressRange", program_module)
5959

60+
# Collect all the module names we saw as events.
61+
module_new_names = []
62+
module_changed_names = []
63+
for module_event in self.dap_server.module_events:
64+
module_name = module_event["body"]["module"]["name"]
65+
reason = module_event["body"]["reason"]
66+
if reason == "new":
67+
module_new_names.append(module_name)
68+
elif reason == "changed":
69+
module_changed_names.append(module_name)
70+
71+
# Make sure we got an event for every active module.
72+
self.assertNotEqual(len(module_new_names), 0)
73+
for module in active_modules:
74+
self.assertIn(module, module_new_names)
75+
76+
# Make sure we got an update event for the program module when the
77+
# symbols got added.
78+
self.assertNotEqual(len(module_changed_names), 0)
79+
self.assertIn(program_module["name"], module_changed_names)
80+
6081
@skipIfWindows
6182
def test_modules(self):
6283
"""

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,11 @@ void DAP::SetTarget(const lldb::SBTarget target) {
702702
lldb::SBListener listener = this->debugger.GetListener();
703703
listener.StartListeningForEvents(
704704
this->target.GetBroadcaster(),
705-
lldb::SBTarget::eBroadcastBitBreakpointChanged);
705+
lldb::SBTarget::eBroadcastBitBreakpointChanged |
706+
lldb::SBTarget::eBroadcastBitModulesLoaded |
707+
lldb::SBTarget::eBroadcastBitModulesUnloaded |
708+
lldb::SBTarget::eBroadcastBitSymbolsLoaded |
709+
lldb::SBTarget::eBroadcastBitSymbolsChanged);
706710
listener.StartListeningForEvents(this->broadcaster,
707711
eBroadcastBitStopEventThread);
708712
}

lldb/tools/lldb-dap/lldb-dap.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,16 @@ void ProgressEventThreadFunction(DAP &dap) {
438438
}
439439
}
440440

441+
static llvm::StringRef GetModuleEventReason(uint32_t event_mask) {
442+
if (event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded)
443+
return "new";
444+
if (event_mask & lldb::SBTarget::eBroadcastBitModulesUnloaded)
445+
return "removed";
446+
assert(event_mask & lldb::SBTarget::eBroadcastBitSymbolsLoaded ||
447+
event_mask & lldb::SBTarget::eBroadcastBitSymbolsChanged);
448+
return "changed";
449+
}
450+
441451
// All events from the debugger, target, process, thread and frames are
442452
// received in this function that runs in its own thread. We are using a
443453
// "FILE *" to output packets back to VS Code and they have mutexes in them
@@ -519,6 +529,28 @@ void EventThreadFunction(DAP &dap) {
519529
(event_mask & lldb::SBProcess::eBroadcastBitSTDERR)) {
520530
SendStdOutStdErr(dap, process);
521531
}
532+
} else if (lldb::SBTarget::EventIsTargetEvent(event)) {
533+
if (event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded ||
534+
event_mask & lldb::SBTarget::eBroadcastBitModulesUnloaded ||
535+
event_mask & lldb::SBTarget::eBroadcastBitSymbolsLoaded ||
536+
event_mask & lldb::SBTarget::eBroadcastBitSymbolsChanged) {
537+
llvm::StringRef reason = GetModuleEventReason(event_mask);
538+
const uint32_t num_modules =
539+
lldb::SBTarget::GetNumModulesFromEvent(event);
540+
for (uint32_t i = 0; i < num_modules; ++i) {
541+
lldb::SBModule module =
542+
lldb::SBTarget::GetModuleAtIndexFromEvent(i, event);
543+
if (!module.IsValid())
544+
continue;
545+
546+
llvm::json::Object body;
547+
body.try_emplace("reason", reason);
548+
body.try_emplace("module", CreateModule(dap.target, module));
549+
llvm::json::Object module_event = CreateEventObject("module");
550+
module_event.try_emplace("body", std::move(body));
551+
dap.SendJSON(llvm::json::Value(std::move(module_event)));
552+
}
553+
}
522554
} else if (lldb::SBBreakpoint::EventIsBreakpointEvent(event)) {
523555
if (event_mask & lldb::SBTarget::eBroadcastBitBreakpointChanged) {
524556
auto event_type =

0 commit comments

Comments
 (0)