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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits