[Lldb-commits] [lldb] Re-land LLDB dap module symbol tables (PR #155021)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Aug 22 12:36:50 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Ely Ronnen (eronnen)
<details>
<summary>Changes</summary>
Re-land the symbol table feature in lldb-dap after it was reverted because of a crash in the `aarch64` tests, which was caused by dereferencing `SBSymbol::GetName` which might return `nullptr` for an invalid symbol.
This patch reapplies the original commits and adds the missing null check.
---
Patch is 72.01 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/155021.diff
38 Files Affected:
- (modified) lldb/include/lldb/API/SBSymbol.h (+15)
- (modified) lldb/include/lldb/API/SBTarget.h (+10)
- (modified) lldb/include/lldb/Symbol/Symbol.h (+5)
- (modified) lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py (+19)
- (modified) lldb/source/API/SBSymbol.cpp (+28)
- (modified) lldb/source/API/SBTarget.cpp (+12)
- (modified) lldb/source/Symbol/Symbol.cpp (+76-68)
- (added) lldb/test/API/tools/lldb-dap/moduleSymbols/Makefile (+3)
- (added) lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py (+37)
- (added) lldb/test/API/tools/lldb-dap/moduleSymbols/main.c (+9)
- (modified) lldb/tools/lldb-dap/CMakeLists.txt (+1)
- (modified) lldb/tools/lldb-dap/DAP.cpp (+22)
- (modified) lldb/tools/lldb-dap/DAP.h (+3)
- (modified) lldb/tools/lldb-dap/EventHelper.cpp (+21-9)
- (modified) lldb/tools/lldb-dap/EventHelper.h (+2-2)
- (modified) lldb/tools/lldb-dap/Handler/ConfigurationDoneRequestHandler.cpp (+5-1)
- (added) lldb/tools/lldb-dap/Handler/ModuleSymbolsRequestHandler.cpp (+90)
- (modified) lldb/tools/lldb-dap/Handler/RequestHandler.h (+14)
- (modified) lldb/tools/lldb-dap/Protocol/DAPTypes.cpp (+34-1)
- (modified) lldb/tools/lldb-dap/Protocol/DAPTypes.h (+32)
- (modified) lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp (+15)
- (modified) lldb/tools/lldb-dap/Protocol/ProtocolRequests.h (+24)
- (modified) lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp (+4)
- (modified) lldb/tools/lldb-dap/Protocol/ProtocolTypes.h (+4-1)
- (modified) lldb/tools/lldb-dap/package-lock.json (+511-2)
- (modified) lldb/tools/lldb-dap/package.json (+30-2)
- (modified) lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts (+4)
- (modified) lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts (+22)
- (modified) lldb/tools/lldb-dap/src-ts/extension.ts (+7-3)
- (added) lldb/tools/lldb-dap/src-ts/index.d.ts (+14)
- (modified) lldb/tools/lldb-dap/src-ts/ui/modules-data-provider.ts (+1)
- (added) lldb/tools/lldb-dap/src-ts/ui/symbols-provider.ts (+127)
- (added) lldb/tools/lldb-dap/src-ts/ui/symbols-webview-html.ts (+51)
- (added) lldb/tools/lldb-dap/src-ts/webview/symbols-table-view.ts (+114)
- (added) lldb/tools/lldb-dap/src-ts/webview/tsconfig.json (+15)
- (modified) lldb/tools/lldb-dap/tsconfig.json (+2)
- (modified) lldb/unittests/DAP/CMakeLists.txt (+1)
- (added) lldb/unittests/DAP/DAPTypesTest.cpp (+60)
``````````diff
diff --git a/lldb/include/lldb/API/SBSymbol.h b/lldb/include/lldb/API/SBSymbol.h
index 94521881f82f9..a93bc7a7ae074 100644
--- a/lldb/include/lldb/API/SBSymbol.h
+++ b/lldb/include/lldb/API/SBSymbol.h
@@ -85,6 +85,12 @@ class LLDB_API SBSymbol {
SymbolType GetType();
+ /// Get the ID of this symbol, usually the original symbol table index.
+ ///
+ /// \returns
+ /// Returns the ID of this symbol.
+ uint32_t GetID();
+
bool operator==(const lldb::SBSymbol &rhs) const;
bool operator!=(const lldb::SBSymbol &rhs) const;
@@ -99,6 +105,15 @@ class LLDB_API SBSymbol {
// other than the actual symbol table itself in the object file.
bool IsSynthetic();
+ /// Returns true if the symbol is a debug symbol.
+ bool IsDebug();
+
+ /// Get the string representation of a symbol type.
+ static const char *GetTypeAsString(lldb::SymbolType symbol_type);
+
+ /// Get the symbol type from a string representation.
+ static lldb::SymbolType GetTypeFromString(const char *str);
+
protected:
lldb_private::Symbol *get();
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 22b6c63ed5b97..62cdd342a05e4 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -324,6 +324,16 @@ class LLDB_API SBTarget {
lldb::SBModule FindModule(const lldb::SBFileSpec &file_spec);
+ /// Find a module with the given module specification.
+ ///
+ /// \param[in] module_spec
+ /// A lldb::SBModuleSpec object that contains module specification.
+ ///
+ /// \return
+ /// A lldb::SBModule object that represents the found module, or an
+ /// invalid SBModule object if no module was found.
+ lldb::SBModule FindModule(const lldb::SBModuleSpec &module_spec);
+
/// Find compile units related to *this target and passed source
/// file.
///
diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h
index 0674e56ef43f5..b994c34e46493 100644
--- a/lldb/include/lldb/Symbol/Symbol.h
+++ b/lldb/include/lldb/Symbol/Symbol.h
@@ -15,6 +15,7 @@
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private.h"
#include "llvm/Support/JSON.h"
@@ -301,6 +302,10 @@ class Symbol : public SymbolContextScope {
bool operator==(const Symbol &rhs) const;
+ static const char *GetTypeAsString(lldb::SymbolType symbol_type);
+
+ static lldb::SymbolType GetTypeFromString(const char *str);
+
protected:
// This is the internal guts of ResolveReExportedSymbol, it assumes
// reexport_name is not null, and that module_spec is valid. We track the
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 311c9f089f86e..0608ac3fd83be 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
@@ -1299,6 +1299,25 @@ def request_modules(
{"command": "modules", "type": "request", "arguments": args_dict}
)
+ def request_moduleSymbols(
+ self,
+ moduleId: str = "",
+ moduleName: str = "",
+ startIndex: int = 0,
+ count: int = 0,
+ ):
+ command_dict = {
+ "command": "__lldb_moduleSymbols",
+ "type": "request",
+ "arguments": {
+ "moduleId": moduleId,
+ "moduleName": moduleName,
+ "startIndex": startIndex,
+ "count": count,
+ },
+ }
+ return self._send_recv(command_dict)
+
def request_stackTrace(
self, threadId=None, startFrame=None, levels=None, format=None, dump=False
):
diff --git a/lldb/source/API/SBSymbol.cpp b/lldb/source/API/SBSymbol.cpp
index 79477dd3a70fc..3b59119494f37 100644
--- a/lldb/source/API/SBSymbol.cpp
+++ b/lldb/source/API/SBSymbol.cpp
@@ -193,6 +193,14 @@ SymbolType SBSymbol::GetType() {
return eSymbolTypeInvalid;
}
+uint32_t SBSymbol::GetID() {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (m_opaque_ptr)
+ return m_opaque_ptr->GetID();
+ return 0;
+}
+
bool SBSymbol::IsExternal() {
LLDB_INSTRUMENT_VA(this);
@@ -208,3 +216,23 @@ bool SBSymbol::IsSynthetic() {
return m_opaque_ptr->IsSynthetic();
return false;
}
+
+bool SBSymbol::IsDebug() {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (m_opaque_ptr)
+ return m_opaque_ptr->IsDebug();
+ return false;
+}
+
+const char *SBSymbol::GetTypeAsString(lldb::SymbolType symbol_type) {
+ LLDB_INSTRUMENT_VA(symbol_type);
+
+ return Symbol::GetTypeAsString(symbol_type);
+}
+
+lldb::SymbolType SBSymbol::GetTypeFromString(const char *str) {
+ LLDB_INSTRUMENT_VA(str);
+
+ return Symbol::GetTypeFromString(str);
+}
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 6aa41c52f3731..eb56337de3c44 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -1570,6 +1570,18 @@ SBModule SBTarget::FindModule(const SBFileSpec &sb_file_spec) {
return sb_module;
}
+SBModule SBTarget::FindModule(const SBModuleSpec &sb_module_spec) {
+ LLDB_INSTRUMENT_VA(this, sb_module_spec);
+
+ SBModule sb_module;
+ if (TargetSP target_sp = GetSP(); target_sp && sb_module_spec.IsValid()) {
+ // The module list is thread safe, no need to lock.
+ sb_module.SetSP(
+ target_sp->GetImages().FindFirstModule(*sb_module_spec.m_opaque_up));
+ }
+ return sb_module;
+}
+
SBSymbolContextList SBTarget::FindCompileUnits(const SBFileSpec &sb_file_spec) {
LLDB_INSTRUMENT_VA(this, sb_file_spec);
diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp
index d6689a647062a..40497dbccc5c3 100644
--- a/lldb/source/Symbol/Symbol.cpp
+++ b/lldb/source/Symbol/Symbol.cpp
@@ -392,45 +392,8 @@ bool Symbol::Compare(ConstString name, SymbolType type) const {
return false;
}
-#define ENUM_TO_CSTRING(x) \
- case eSymbolType##x: \
- return #x;
-
const char *Symbol::GetTypeAsString() const {
- switch (m_type) {
- ENUM_TO_CSTRING(Invalid);
- ENUM_TO_CSTRING(Absolute);
- ENUM_TO_CSTRING(Code);
- ENUM_TO_CSTRING(Resolver);
- ENUM_TO_CSTRING(Data);
- ENUM_TO_CSTRING(Trampoline);
- ENUM_TO_CSTRING(Runtime);
- ENUM_TO_CSTRING(Exception);
- ENUM_TO_CSTRING(SourceFile);
- ENUM_TO_CSTRING(HeaderFile);
- ENUM_TO_CSTRING(ObjectFile);
- ENUM_TO_CSTRING(CommonBlock);
- ENUM_TO_CSTRING(Block);
- ENUM_TO_CSTRING(Local);
- ENUM_TO_CSTRING(Param);
- ENUM_TO_CSTRING(Variable);
- ENUM_TO_CSTRING(VariableType);
- ENUM_TO_CSTRING(LineEntry);
- ENUM_TO_CSTRING(LineHeader);
- ENUM_TO_CSTRING(ScopeBegin);
- ENUM_TO_CSTRING(ScopeEnd);
- ENUM_TO_CSTRING(Additional);
- ENUM_TO_CSTRING(Compiler);
- ENUM_TO_CSTRING(Instrumentation);
- ENUM_TO_CSTRING(Undefined);
- ENUM_TO_CSTRING(ObjCClass);
- ENUM_TO_CSTRING(ObjCMetaClass);
- ENUM_TO_CSTRING(ObjCIVar);
- ENUM_TO_CSTRING(ReExported);
- default:
- break;
- }
- return "<unknown SymbolType>";
+ return GetTypeAsString(static_cast<lldb::SymbolType>(m_type));
}
void Symbol::CalculateSymbolContext(SymbolContext *sc) {
@@ -774,6 +737,79 @@ bool Symbol::operator==(const Symbol &rhs) const {
return true;
}
+#define ENUM_TO_CSTRING(x) \
+ case eSymbolType##x: \
+ return #x;
+
+const char *Symbol::GetTypeAsString(lldb::SymbolType symbol_type) {
+ switch (symbol_type) {
+ ENUM_TO_CSTRING(Invalid);
+ ENUM_TO_CSTRING(Absolute);
+ ENUM_TO_CSTRING(Code);
+ ENUM_TO_CSTRING(Resolver);
+ ENUM_TO_CSTRING(Data);
+ ENUM_TO_CSTRING(Trampoline);
+ ENUM_TO_CSTRING(Runtime);
+ ENUM_TO_CSTRING(Exception);
+ ENUM_TO_CSTRING(SourceFile);
+ ENUM_TO_CSTRING(HeaderFile);
+ ENUM_TO_CSTRING(ObjectFile);
+ ENUM_TO_CSTRING(CommonBlock);
+ ENUM_TO_CSTRING(Block);
+ ENUM_TO_CSTRING(Local);
+ ENUM_TO_CSTRING(Param);
+ ENUM_TO_CSTRING(Variable);
+ ENUM_TO_CSTRING(VariableType);
+ ENUM_TO_CSTRING(LineEntry);
+ ENUM_TO_CSTRING(LineHeader);
+ ENUM_TO_CSTRING(ScopeBegin);
+ ENUM_TO_CSTRING(ScopeEnd);
+ ENUM_TO_CSTRING(Additional);
+ ENUM_TO_CSTRING(Compiler);
+ ENUM_TO_CSTRING(Instrumentation);
+ ENUM_TO_CSTRING(Undefined);
+ ENUM_TO_CSTRING(ObjCClass);
+ ENUM_TO_CSTRING(ObjCMetaClass);
+ ENUM_TO_CSTRING(ObjCIVar);
+ ENUM_TO_CSTRING(ReExported);
+ }
+ return "<unknown SymbolType>";
+}
+
+lldb::SymbolType Symbol::GetTypeFromString(const char *str) {
+ std::string str_lower = llvm::StringRef(str).lower();
+ return llvm::StringSwitch<lldb::SymbolType>(str_lower)
+ .Case("absolute", eSymbolTypeAbsolute)
+ .Case("code", eSymbolTypeCode)
+ .Case("resolver", eSymbolTypeResolver)
+ .Case("data", eSymbolTypeData)
+ .Case("trampoline", eSymbolTypeTrampoline)
+ .Case("runtime", eSymbolTypeRuntime)
+ .Case("exception", eSymbolTypeException)
+ .Case("sourcefile", eSymbolTypeSourceFile)
+ .Case("headerfile", eSymbolTypeHeaderFile)
+ .Case("objectfile", eSymbolTypeObjectFile)
+ .Case("commonblock", eSymbolTypeCommonBlock)
+ .Case("block", eSymbolTypeBlock)
+ .Case("local", eSymbolTypeLocal)
+ .Case("param", eSymbolTypeParam)
+ .Case("variable", eSymbolTypeVariable)
+ .Case("variableType", eSymbolTypeVariableType)
+ .Case("lineentry", eSymbolTypeLineEntry)
+ .Case("lineheader", eSymbolTypeLineHeader)
+ .Case("scopebegin", eSymbolTypeScopeBegin)
+ .Case("scopeend", eSymbolTypeScopeEnd)
+ .Case("additional,", eSymbolTypeAdditional)
+ .Case("compiler", eSymbolTypeCompiler)
+ .Case("instrumentation", eSymbolTypeInstrumentation)
+ .Case("undefined", eSymbolTypeUndefined)
+ .Case("objcclass", eSymbolTypeObjCClass)
+ .Case("objcmetaclass", eSymbolTypeObjCMetaClass)
+ .Case("objcivar", eSymbolTypeObjCIVar)
+ .Case("reexported", eSymbolTypeReExported)
+ .Default(eSymbolTypeInvalid);
+}
+
namespace llvm {
namespace json {
@@ -804,36 +840,8 @@ bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSymbol &symbol,
bool fromJSON(const llvm::json::Value &value, lldb::SymbolType &type,
llvm::json::Path path) {
if (auto str = value.getAsString()) {
- type = llvm::StringSwitch<lldb::SymbolType>(*str)
- .Case("absolute", eSymbolTypeAbsolute)
- .Case("code", eSymbolTypeCode)
- .Case("resolver", eSymbolTypeResolver)
- .Case("data", eSymbolTypeData)
- .Case("trampoline", eSymbolTypeTrampoline)
- .Case("runtime", eSymbolTypeRuntime)
- .Case("exception", eSymbolTypeException)
- .Case("sourcefile", eSymbolTypeSourceFile)
- .Case("headerfile", eSymbolTypeHeaderFile)
- .Case("objectfile", eSymbolTypeObjectFile)
- .Case("commonblock", eSymbolTypeCommonBlock)
- .Case("block", eSymbolTypeBlock)
- .Case("local", eSymbolTypeLocal)
- .Case("param", eSymbolTypeParam)
- .Case("variable", eSymbolTypeVariable)
- .Case("variableType", eSymbolTypeVariableType)
- .Case("lineentry", eSymbolTypeLineEntry)
- .Case("lineheader", eSymbolTypeLineHeader)
- .Case("scopebegin", eSymbolTypeScopeBegin)
- .Case("scopeend", eSymbolTypeScopeEnd)
- .Case("additional,", eSymbolTypeAdditional)
- .Case("compiler", eSymbolTypeCompiler)
- .Case("instrumentation", eSymbolTypeInstrumentation)
- .Case("undefined", eSymbolTypeUndefined)
- .Case("objcclass", eSymbolTypeObjCClass)
- .Case("objcmetaClass", eSymbolTypeObjCMetaClass)
- .Case("objcivar", eSymbolTypeObjCIVar)
- .Case("reexporte", eSymbolTypeReExported)
- .Default(eSymbolTypeInvalid);
+ llvm::StringRef str_ref = str.value_or("");
+ type = Symbol::GetTypeFromString(str_ref.data());
if (type == eSymbolTypeInvalid) {
path.report("invalid symbol type");
diff --git a/lldb/test/API/tools/lldb-dap/moduleSymbols/Makefile b/lldb/test/API/tools/lldb-dap/moduleSymbols/Makefile
new file mode 100644
index 0000000000000..10495940055b6
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/moduleSymbols/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py b/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py
new file mode 100644
index 0000000000000..b99edf369a7fd
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py
@@ -0,0 +1,37 @@
+"""
+Test lldb-dap moduleSymbols request
+"""
+
+import lldbdap_testcase
+
+
+class TestDAP_moduleSymbols(lldbdap_testcase.DAPTestCaseBase):
+ def test_moduleSymbols(self):
+ """
+ Test that the moduleSymbols request returns correct symbols from the module.
+ """
+ program = self.getBuildArtifact("a.out")
+ self.build_and_launch(program)
+
+ symbol_names = []
+ i = 0
+ while True:
+ next_symbol = self.dap_server.request_moduleSymbols(
+ moduleName="a.out", startIndex=i, count=1
+ )
+ self.assertIn("symbols", next_symbol["body"])
+ result_symbols = next_symbol["body"]["symbols"]
+ self.assertLessEqual(len(result_symbols), 1)
+ if len(result_symbols) == 0:
+ break
+
+ self.assertIn("name", result_symbols[0])
+ symbol_names.append(result_symbols[0]["name"])
+ i += 1
+ if i >= 1000:
+ break
+
+ self.assertGreater(len(symbol_names), 0)
+ self.assertIn("main", symbol_names)
+ self.assertIn("func1", symbol_names)
+ self.assertIn("func2", symbol_names)
diff --git a/lldb/test/API/tools/lldb-dap/moduleSymbols/main.c b/lldb/test/API/tools/lldb-dap/moduleSymbols/main.c
new file mode 100644
index 0000000000000..b038b10480b80
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/moduleSymbols/main.c
@@ -0,0 +1,9 @@
+int func1() { return 42; }
+
+int func2() { return 84; }
+
+int main() {
+ func1();
+ func2();
+ return 0;
+}
diff --git a/lldb/tools/lldb-dap/CMakeLists.txt b/lldb/tools/lldb-dap/CMakeLists.txt
index 5e0ad53b82f89..7db334ca56bcf 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -45,6 +45,7 @@ add_lldb_library(lldbDAP
Handler/LaunchRequestHandler.cpp
Handler/LocationsRequestHandler.cpp
Handler/ModulesRequestHandler.cpp
+ Handler/ModuleSymbolsRequestHandler.cpp
Handler/NextRequestHandler.cpp
Handler/PauseRequestHandler.cpp
Handler/ReadMemoryRequestHandler.cpp
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 0ecd5f05c73bb..b1ad38d983893 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -1261,6 +1261,27 @@ protocol::Capabilities DAP::GetCapabilities() {
return capabilities;
}
+protocol::Capabilities DAP::GetCustomCapabilities() {
+ protocol::Capabilities capabilities;
+
+ // Add all custom capabilities here.
+ const llvm::DenseSet<AdapterFeature> all_custom_features = {
+ protocol::eAdapterFeatureSupportsModuleSymbolsRequest,
+ };
+
+ for (auto &kv : request_handlers) {
+ llvm::SmallDenseSet<AdapterFeature, 1> features =
+ kv.second->GetSupportedFeatures();
+
+ for (auto &feature : features) {
+ if (all_custom_features.contains(feature))
+ capabilities.supportedFeatures.insert(feature);
+ }
+ }
+
+ return capabilities;
+}
+
void DAP::StartEventThread() {
event_thread = std::thread(&DAP::EventThread, this);
}
@@ -1617,6 +1638,7 @@ void DAP::RegisterRequests() {
// Custom requests
RegisterRequest<CompileUnitsRequestHandler>();
RegisterRequest<ModulesRequestHandler>();
+ RegisterRequest<ModuleSymbolsRequestHandler>();
// Testing requests
RegisterRequest<TestGetTargetBreakpointsRequestHandler>();
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 0b6373fb80381..04f70f76a09cd 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -367,6 +367,9 @@ struct DAP final : private DAPTransport::MessageHandler {
/// The set of capabilities supported by this adapter.
protocol::Capabilities GetCapabilities();
+ /// The set of custom capabilities supported by this adapter.
+ protocol::Capabilities GetCustomCapabilities();
+
/// Debuggee will continue from stopped state.
void WillContinue() { variables.Clear(); }
diff --git a/lldb/tools/lldb-dap/EventHelper.cpp b/lldb/tools/lldb-dap/EventHelper.cpp
index 364cc7ab4ef8c..bfb05a387d04d 100644
--- a/lldb/tools/lldb-dap/EventHelper.cpp
+++ b/lldb/tools/lldb-dap/EventHelper.cpp
@@ -38,25 +38,37 @@ static void SendThreadExitedEvent(DAP &dap, lldb::tid_t tid) {
dap.SendJSON(llvm::json::Value(std::move(event)));
}
-void SendTargetBasedCapabilities(DAP &dap) {
+/// Get capabilities based on the configured target.
+static llvm::DenseSet<AdapterFeature> GetTargetBasedCapabilities(DAP &dap) {
+ llvm::DenseSet<AdapterFeature> capabilities;
if (!dap.target.IsValid())
- return;
-
- protocol::CapabilitiesEventBody body;
+ return capabilities;
const llvm::StringRef target_triple = dap.target.GetTriple();
if (target_triple.starts_with("x86"))
- body.capabilities.supportedFeatures.insert(
- protocol::eAdapterFeatureStepInTargetsRequest);
+ capabilities.insert(protocol::eAdapterFeatureStepInTargetsRequest);
// We only support restarting launch requests not attach requests.
if (dap.last_launch_request)
- body.capabilities.supportedFeatures.insert(
- protocol::eAdapterFeatureRestartRequest);
+ capabilities.insert(protocol::eAdapterFeatureRestartRequest);
+
+ return capabilities;
+}
+
+void SendExtraCapabilities(DAP &dap) {
+ protocol::Capabilities capabilities = dap.GetCustomCapabilities();
+ llvm::DenseSet<AdapterFeature> target_capabilities =
+ GetTargetBasedCapabilities(dap);
+
+ capabilities.supportedFeatures.insert(target_capabilities.begin(),
+ target_capabilities.end());
+
+ protocol::CapabilitiesEventBody body;
+ body.capabilities = std::move(capabilities);
// Only notify the client if supportedFeatures changed.
if (!body.capabilities.supportedFeatures.empty())
- dap.Send(protocol::Event{"capabilities", body});
+ dap.Send(protocol::Event{"capabilities", std::move(body)});
}
// "ProcessEvent": {
diff --git a/lldb/tools/lldb-dap/EventHelper.h b/lldb/tools/lldb-dap/EventHelper.h
index 72ad5308a2b0c..592c1b81c46af 100644
--- a/lldb/tools/lldb-dap/EventHelper.h
+++ b/lldb/tools/lldb-dap/EventHelper.h
@@ -17,8 +17,8 @@ struct DAP;
enum LaunchMethod { Launch, Attach, AttachForSuspendedLaunch };
-/// Update capabilities based on the configured target.
-void SendTargetBasedCapabilities(DAP &dap);
+/// Sends target based capabilities and lldb-dap custom capabilities.
+void SendExtraCapabilities(DAP &dap);
void SendProcessEvent(DAP &dap, LaunchMethod launch_method);
diff --git a/lldb/tools/lldb-dap/Handler/ConfigurationDoneRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/ConfigurationDoneRequestHandler.cpp
index e7735a705d0aa..1bfe7b7f6ef5c 100644
--- a/lldb/tools/lldb-dap/Handler/ConfigurationDoneRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/ConfigurationDoneRequestHandler.cpp
@@ -9,6 +9,7 @@
#include "DAP.h"
#include "EventHelper.h"
#include "LLDBUtils.h"
+#include "Protocol/ProtocolEvents.h"
#include "Protocol/ProtocolRequests.h"
#include "ProtocolUtils.h"
#include "RequestHandler.h"
@@ -44,7 +45,10 @@ ConfigurationDoneRequestHandler::Run(const ConfigurationDoneArguments &) const {
// Waiting until 'configurationDone' to send target based capabilities in case
// the launch or attach scripts adjust the target. The initial dummy target
// may have different capabilities than the final target.
- SendTargetBasedCapabilities(dap);
+
+ /// ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/155021
More information about the lldb-commits
mailing list