aelitashen created this revision.
aelitashen added reviewers: wallace, clayborg.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.
Make lldb-vscode receive and process module events so that modules can be
rendered in the IDE.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D82477
Files:
lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
lldb/test/API/tools/lldb-vscode/module/Makefile
lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
lldb/test/API/tools/lldb-vscode/module/main.cpp
lldb/tools/lldb-vscode/JSONUtils.cpp
lldb/tools/lldb-vscode/JSONUtils.h
lldb/tools/lldb-vscode/VSCode.cpp
lldb/tools/lldb-vscode/lldb-vscode.cpp
Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -39,6 +39,7 @@
#include <set>
#include <sstream>
#include <thread>
+#include <vector>
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Option/Arg.h"
@@ -433,6 +434,30 @@
g_vsc.SendJSON(llvm::json::Value(std::move(bp_event)));
}
}
+ } else if (lldb::SBTarget::EventIsTargetEvent(event)) {
+ if (event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded ||
+ event_mask & lldb::SBTarget::eBroadcastBitModulesUnloaded ||
+ event_mask & lldb::SBTarget::eBroadcastBitSymbolsLoaded) {
+ int solib_count = lldb::SBTarget::GetNumModulesFromEvent(event);
+ int i = 0;
+ while (i < solib_count) {
+ auto module = lldb::SBTarget::GetModuleAtIndexFromEvent(i, event);
+ i++;
+ auto module_event = CreateEventObject("module");
+ llvm::json::Value module_value = CreateModule(module);
+ llvm::json::Object body;
+ if (event_mask & lldb::SBTarget::eBroadcastBitModulesLoaded) {
+ body.try_emplace("reason", "new");
+ } else if (event_mask & lldb::SBTarget::eBroadcastBitModulesUnloaded) {
+ body.try_emplace("reason", "removed");
+ } else if (event_mask & lldb::SBTarget::eBroadcastBitSymbolsLoaded) {
+ body.try_emplace("reason", "changed");
+ }
+ body.try_emplace("module", module_value);
+ module_event.try_emplace("body", std::move(body));
+ g_vsc.SendJSON(llvm::json::Value(std::move(module_event)));
+ }
+ }
} else if (event.BroadcasterMatchesRef(g_vsc.broadcaster)) {
if (event_mask & eBroadcastBitStopEventThread) {
done = true;
Index: lldb/tools/lldb-vscode/VSCode.cpp
===================================================================
--- lldb/tools/lldb-vscode/VSCode.cpp
+++ lldb/tools/lldb-vscode/VSCode.cpp
@@ -354,6 +354,9 @@
lldb::SBTarget::eBroadcastBitBreakpointChanged);
listener.StartListeningForEvents(this->broadcaster,
eBroadcastBitStopEventThread);
+ listener.StartListeningForEvents(
+ this->target.GetBroadcaster(),
+ lldb::SBTarget::eBroadcastBitModulesLoaded | lldb::SBTarget::eBroadcastBitModulesUnloaded);
}
}
Index: lldb/tools/lldb-vscode/JSONUtils.h
===================================================================
--- lldb/tools/lldb-vscode/JSONUtils.h
+++ lldb/tools/lldb-vscode/JSONUtils.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/JSON.h"
#include "VSCodeForward.h"
+#include "lldb/API/SBModule.h"
namespace lldb_vscode {
@@ -237,6 +238,8 @@
llvm::Optional<llvm::StringRef> request_path = llvm::None,
llvm::Optional<uint32_t> request_line = llvm::None);
+llvm::json::Value CreateModule(lldb::SBModule &module);
+
/// Create a "Event" JSON object using \a event_name as the event name
///
/// \param[in] event_name
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===================================================================
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -327,6 +327,25 @@
return llvm::json::Value(std::move(object));
}
+llvm::json::Value CreateModule(lldb::SBModule &module) {
+ llvm::json::Object object;
+ if (!module.IsValid())
+ return llvm::json::Value(std::move(object));
+ object.try_emplace("id", std::string(module.GetUUIDString()));
+ object.try_emplace("name", std::string(module.GetFileSpec().GetFilename())); // Path in remote
+ std::string module_path = std::string(module.GetFileSpec().GetDirectory()) + "/" + std::string(module.GetFileSpec().GetFilename());
+ object.try_emplace("path", module_path);
+ if (module.GetNumCompileUnits() > 0) {
+ object.try_emplace("symbolStatus", "Symbols loaded.");
+ std::string symbol_path = std::string(module.GetSymbolFileSpec().GetDirectory()) + "/" + std::string(module.GetSymbolFileSpec().GetFilename());
+ object.try_emplace("symbolFilePath", symbol_path);
+ }
+ std::string loaded_addr = std::to_string(module.GetObjectFileHeaderAddress().GetLoadAddress(g_vsc.target));
+ object.try_emplace("addressRange", loaded_addr);
+ return llvm::json::Value(std::move(object));
+
+}
+
void AppendBreakpoint(lldb::SBBreakpoint &bp, llvm::json::Array &breakpoints,
llvm::Optional<llvm::StringRef> request_path,
llvm::Optional<uint32_t> request_line) {
Index: lldb/test/API/tools/lldb-vscode/module/main.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/module/main.cpp
@@ -0,0 +1,9 @@
+
+int multiply(int x, int y) {
+ return x * y; // breakpoint 1
+}
+
+int main(int argc, char const *argv[]) {
+ int result = multiply(argc, 20);
+ return result < 0;
+}
Index: lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
@@ -0,0 +1,30 @@
+"""
+Test lldb-vscode setBreakpoints request
+"""
+
+from __future__ import print_function
+
+import unittest2
+import vscode
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbvscode_testcase
+
+
+class TestVSCode_module(lldbvscode_testcase.VSCodeTestCaseBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_modules_event(self):
+ program= self.getBuildArtifact("a.out")
+ self.build_and_launch(program)
+ source = "main.cpp"
+ breakpoint1_line = line_number(source, '// breakpoint 1')
+ lines = [breakpoint1_line]
+ breakpoint_ids = self.set_source_breakpoints(source, lines)
+ self.continue_to_breakpoints(breakpoint_ids)
+ self.assertTrue('a.out' in self.vscode.get_active_modules(),
+ 'Module: a.out is loaded')
+ self.assertTrue('symbolFilePath' in self.vscode.get_active_modules()['a.out'],
+ 'Symbol exists')
\ No newline at end of file
Index: lldb/test/API/tools/lldb-vscode/module/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/module/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
@@ -112,6 +112,7 @@
self.initialize_body = None
self.thread_stop_reasons = {}
self.breakpoint_events = []
+ self.module_events = {}
self.sequence = 1
self.threads = None
self.recv_thread.start()
@@ -132,6 +133,9 @@
if command['seq'] != response['request_seq']:
raise ValueError('seq mismatch in response')
+ def get_active_modules(self):
+ return self.module_events
+
def get_output(self, category, timeout=0.0, clear=True):
self.output_condition.acquire()
output = None
@@ -208,6 +212,15 @@
self.breakpoint_events.append(packet)
# no need to add 'breakpoint' event packets to our packets list
return keepGoing
+ elif event == 'module':
+ reason = body['reason']
+ if (reason == 'new' or reason == 'changed'):
+ self.module_events[body['module']['name']] = body['module']
+ elif reason == 'removed':
+ if body['module']['name'] in self.module_events:
+ self.module_events.pop(body['module']['name'])
+ return keepGoing
+
elif packet_type == 'response':
if packet['command'] == 'disconnect':
keepGoing = False
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits