[Lldb-commits] [lldb] [LLDB] Consolidate C++ string buffer summaries (PR #144258)
@@ -199,13 +183,13 @@ bool lldb_private::formatters::WCharSummaryProvider( options.SetBinaryZeroIsTerminator(false); switch (wchar_size) { - case 8: + case 1: Nerixyz wrote: I refactored it to use `valobj.GetCompilerType().GetBasicTypeFromAST()` now. https://github.com/llvm/llvm-project/pull/144258 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] move XcodeSDK's sysroot into a separate class (PR #144396)
Michael137 wrote: Looks plausible. Out of curiosity, why is this needed to implement `GetSDKPathFromDebugInfo` on Windows? Is there a follow-up PR already up? https://github.com/llvm/llvm-project/pull/144396 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Expose enumerator for separate-debug-info in SBModule (PR #144119)
Jlalond wrote: > However, FileSpecList already has an AppendIfUnique method. So you could > (with less code than the current implementation) have all the new > lldb_private API's return what consumers actually want: an FileSpecList, and > then that would be trivially convertible to the SBFileSpecList, which is in > the end what you wanted to expose. Good suggestion @jimingham, I also added a constructor to move a FileSpecList into the SBFileSpecList. The code is much cleaner now as you expected. https://github.com/llvm/llvm-project/pull/144119 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Consolidate C++ string buffer summaries (PR #144258)
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/144258 >From 7f6218a5b23231032988fe1e2d5d451fd5cf2e19 Mon Sep 17 00:00:00 2001 From: Nerixyz Date: Sun, 15 Jun 2025 12:23:27 +0200 Subject: [PATCH] [LLDB] Consolidate C++ string buffer summaries --- .../Language/CPlusPlus/CxxStringTypes.cpp | 102 +--- .../Language/CPlusPlus/CxxStringTypes.h | 29 .../Plugins/Language/CPlusPlus/LibCxx.cpp | 147 -- .../string/TestDataFormatterLibcxxString.py | 8 +- .../TestDataFormatterLibcxxStringView.py | 8 +- 5 files changed, 148 insertions(+), 146 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index fc17b76804d9f..bf8c393445908 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -116,15 +116,7 @@ bool lldb_private::formatters::WCharStringSummaryProvider( return false; // Get a wchar_t basic type from the current type system - CompilerType wchar_compiler_type = - valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); - - if (!wchar_compiler_type) -return false; - - // Safe to pass nullptr for exe_scope here. - std::optional size = - llvm::expectedToOptional(wchar_compiler_type.GetBitSize(nullptr)); + std::optional size = GetWCharByteSize(valobj); if (!size) return false; const uint32_t wchar_size = *size; @@ -136,13 +128,13 @@ bool lldb_private::formatters::WCharStringSummaryProvider( options.SetPrefixToken("L"); switch (wchar_size) { - case 8: + case 1: return StringPrinter::ReadStringAndDumpToStream( options); - case 16: + case 2: return StringPrinter::ReadStringAndDumpToStream( options); - case 32: + case 4: return StringPrinter::ReadStringAndDumpToStream( options); default: @@ -177,15 +169,7 @@ bool lldb_private::formatters::WCharSummaryProvider( return false; // Get a wchar_t basic type from the current type system - CompilerType wchar_compiler_type = - valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); - - if (!wchar_compiler_type) -return false; - -// Safe to pass nullptr for exe_scope here. - std::optional size = - llvm::expectedToOptional(wchar_compiler_type.GetBitSize(nullptr)); + std::optional size = GetWCharByteSize(valobj); if (!size) return false; const uint32_t wchar_size = *size; @@ -199,13 +183,13 @@ bool lldb_private::formatters::WCharSummaryProvider( options.SetBinaryZeroIsTerminator(false); switch (wchar_size) { - case 8: + case 1: return StringPrinter::ReadBufferAndDumpToStream( options); - case 16: + case 2: return StringPrinter::ReadBufferAndDumpToStream( options); - case 32: + case 4: return StringPrinter::ReadBufferAndDumpToStream( options); default: @@ -214,3 +198,73 @@ bool lldb_private::formatters::WCharSummaryProvider( } return true; } + +std::optional +lldb_private::formatters::GetWCharByteSize(ValueObject &valobj) { + return llvm::expectedToOptional( + valobj.GetCompilerType() + .GetBasicTypeFromAST(lldb::eBasicTypeWChar) + .GetByteSize(nullptr)); +} + +template +bool lldb_private::formatters::StringBufferSummaryProvider( +Stream &stream, const TypeSummaryOptions &summary_options, +lldb::ValueObjectSP location_sp, uint64_t size, std::string prefix_token) { + + if (size == 0) { +stream.PutCString(prefix_token); +stream.PutCString("\"\""); +return true; + } + + if (!location_sp) +return false; + + StringPrinter::ReadBufferAndDumpToStreamOptions options(*location_sp); + + if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { +const auto max_size = +location_sp->GetTargetSP()->GetMaximumSizeOfStringSummary(); +if (size > max_size) { + size = max_size; + options.SetIsTruncated(true); +} + } + + { +DataExtractor extractor; +const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); +if (bytes_read < size) + return false; + +options.SetData(std::move(extractor)); + } + options.SetStream(&stream); + if (prefix_token.empty()) +options.SetPrefixToken(nullptr); + else +options.SetPrefixToken(prefix_token); + options.SetQuote('"'); + options.SetSourceSize(size); + options.SetBinaryZeroIsTerminator(false); + return StringPrinter::ReadBufferAndDumpToStream(options); +} + +// explicit instantiations for all string element types +template bool +lldb_private::formatters::StringBufferSummaryProvider( +Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t, +std::string); +template bool +lldb_private::formatters::StringBufferSummaryProvider( +Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t, +std:
[Lldb-commits] [lldb] [lldb-dap] Fix source references (PR #144364)
@@ -510,6 +510,25 @@ DAP::SendFormattedOutput(OutputType o, const char *format, ...) { o, llvm::StringRef(buffer, std::min(actual_length, sizeof(buffer; } +int32_t DAP::CreateSourceReference(lldb::addr_t address) { + auto iter = llvm::find(source_references, address); + if (iter != source_references.end()) +return std::distance(source_references.begin(), iter) + 1; + + source_references.emplace_back(address); + return static_cast(source_references.size()); ashgti wrote: We may need a mutex around this since the event thread could also interact with the list of source references. https://github.com/llvm/llvm-project/pull/144364 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Fix source references (PR #144364)
@@ -510,6 +510,25 @@ DAP::SendFormattedOutput(OutputType o, const char *format, ...) { o, llvm::StringRef(buffer, std::min(actual_length, sizeof(buffer; } +int32_t DAP::CreateSourceReference(lldb::addr_t address) { + auto iter = llvm::find(source_references, address); ashgti wrote: Should we use a `llvm::DenseMap` so this doesn't have to be as linear when searching for an address? https://github.com/llvm/llvm-project/pull/144364 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Fix source references (PR #144364)
@@ -37,10 +37,15 @@ protocol::Source CreateSource(const lldb::SBFileSpec &file); /// \param[in] target /// The target that has the address. /// +/// \param[in] create_reference +/// function used to create a source_reference +/// /// \return -/// A "Source" JSON object that follows the formal JSON +/// An optional "Source" JSON object that follows the formal JSON /// definition outlined by Microsoft. -protocol::Source CreateSource(lldb::SBAddress address, lldb::SBTarget &target); +std::optional +CreateSource(lldb::SBAddress address, lldb::SBTarget &target, + llvm::function_ref create_reference); ashgti wrote: Should we move this into the `DAP`? Something like `optional DAP::ResolveSource(SBAddress, SBTarget);` that creates or returns a source for the given address? Or we could move the actual address info into the `adapterData` field and then we don't need to track the address in the DAP, we'd just need to have some way of hashing the address into a unique `sourceReference`. https://github.com/llvm/llvm-project/pull/144364 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Fix source references (PR #144364)
@@ -510,6 +510,25 @@ DAP::SendFormattedOutput(OutputType o, const char *format, ...) { o, llvm::StringRef(buffer, std::min(actual_length, sizeof(buffer; } +int32_t DAP::CreateSourceReference(lldb::addr_t address) { + auto iter = llvm::find(source_references, address); da-viper wrote: I used the vector since we are less likely to create up 100 source references thoughout a debug session. Will be faster than hashmap because of the small size. Could move to densemap if preferred. https://github.com/llvm/llvm-project/pull/144364 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] c9ac167 - [lldb] Remove a redundant control flow statement (NFC) (#144284)
Author: Kazu Hirata Date: 2025-06-16T08:59:10-07:00 New Revision: c9ac1679b5d3a3839640486dd4bd931a19f4725a URL: https://github.com/llvm/llvm-project/commit/c9ac1679b5d3a3839640486dd4bd931a19f4725a DIFF: https://github.com/llvm/llvm-project/commit/c9ac1679b5d3a3839640486dd4bd931a19f4725a.diff LOG: [lldb] Remove a redundant control flow statement (NFC) (#144284) Added: Modified: lldb/tools/debugserver/source/RNBRemote.cpp Removed: diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 391d1c50168ea..8be384c6d24af 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -1476,7 +1476,6 @@ bool RNBRemote::InitializeRegisters(bool force) { void RNBRemote::NotifyThatProcessStopped(void) { RNBRemote::HandlePacket_last_signal(NULL); - return; } /* 'A arglen,argnum,arg,...' ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Remove a redundant control flow statement (NFC) (PR #144284)
https://github.com/kazutakahirata closed https://github.com/llvm/llvm-project/pull/144284 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix FindProcessImpl() for iOS simulators (PR #139174)
https://github.com/royitaqi updated https://github.com/llvm/llvm-project/pull/139174 >From d98210b81f7b49f5384e968b1a18e00e432aaf2c Mon Sep 17 00:00:00 2001 From: Roy Shi Date: Thu, 8 May 2025 16:21:53 -0700 Subject: [PATCH] Fix macOS FindProcessImpl() --- lldb/source/Host/macosx/objcxx/Host.mm | 25 +++-- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lldb/source/Host/macosx/objcxx/Host.mm b/lldb/source/Host/macosx/objcxx/Host.mm index e187bf98188ae..e8a1c597eea53 100644 --- a/lldb/source/Host/macosx/objcxx/Host.mm +++ b/lldb/source/Host/macosx/objcxx/Host.mm @@ -595,7 +595,9 @@ DataExtractor data(arg_data.GetBytes(), arg_data_size, const llvm::Triple::ArchType triple_arch = triple.getArch(); const bool check_for_ios_simulator = (triple_arch == llvm::Triple::x86 || - triple_arch == llvm::Triple::x86_64); + triple_arch == llvm::Triple::x86_64 || + triple_arch == llvm::Triple::aarch64); + const char *cstr = data.GetCStr(&offset); if (cstr) { process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native); @@ -621,22 +623,25 @@ DataExtractor data(arg_data.GetBytes(), arg_data_size, } Environment &proc_env = process_info.GetEnvironment(); + bool is_simulator = false; while ((cstr = data.GetCStr(&offset))) { if (cstr[0] == '\0') break; -if (check_for_ios_simulator) { - if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == - 0) -process_info.GetArchitecture().GetTriple().setOS( -llvm::Triple::IOS); - else -process_info.GetArchitecture().GetTriple().setOS( -llvm::Triple::MacOSX); -} +if (check_for_ios_simulator && +strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == +0) + is_simulator = true; proc_env.insert(cstr); } + llvm::Triple &triple = process_info.GetArchitecture().GetTriple(); + if (is_simulator) { +triple.setOS(llvm::Triple::IOS); +triple.setEnvironment(llvm::Triple::Simulator); + } else { +triple.setOS(llvm::Triple::MacOSX); + } return true; } } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add DWARFExpressionEntry and GetExpressionEntryAtAddress() to … (PR #144238)
@@ -53,6 +53,27 @@ bool DWARFExpressionList::ContainsAddress(lldb::addr_t func_load_addr, return GetExpressionAtAddress(func_load_addr, addr) != nullptr; } +llvm::Expected +DWARFExpressionList::GetExpressionEntryAtAddress(lldb::addr_t func_load_addr, + lldb::addr_t load_addr) const { + if (const DWARFExpression *expr = GetAlwaysValidExpr()) { +return DWARFExpressionEntry{0, LLDB_INVALID_ADDRESS, expr}; + } + + if (func_load_addr == LLDB_INVALID_ADDRESS) +func_load_addr = m_func_file_addr; + + addr_t addr = load_addr - func_load_addr + m_func_file_addr; + uint32_t index = m_exprs.FindEntryIndexThatContains(addr); + if (index == UINT32_MAX) { +return llvm::createStringError(llvm::inconvertibleErrorCode(), + "No DWARF expression found for address 0x%llx", addr); + } + + const Entry &entry = *m_exprs.GetEntryAtIndex(index); + return DWARFExpressionEntry{entry.base, entry.GetRangeEnd(), &entry.data}; +} + const DWARFExpression * DWARFExpressionList::GetExpressionAtAddress(lldb::addr_t func_load_addr, adrian-prantl wrote: Out of curiosity: Do we still need this API, or is it just a subset of the function above? https://github.com/llvm/llvm-project/pull/144238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] d1dc080 - [lldb-dap] show function name in the instruction comment. (#144070)
Author: Ebuka Ezike Date: 2025-06-16T17:53:34+01:00 New Revision: d1dc080a858ca47c314334fb14f1ecb605fb4371 URL: https://github.com/llvm/llvm-project/commit/d1dc080a858ca47c314334fb14f1ecb605fb4371 DIFF: https://github.com/llvm/llvm-project/commit/d1dc080a858ca47c314334fb14f1ecb605fb4371.diff LOG: [lldb-dap] show function name in the instruction comment. (#144070) putting the function name is the dissassembly instruction messes up the alignment making it less readable. put it instead with the comment. This also aligns the opcodes and instruction to the left matching the cli Added: Modified: lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp Removed: diff --git a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp index d5878d18289d6..85214b84b5c9c 100644 --- a/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp @@ -100,7 +100,7 @@ static DisassembledInstruction ConvertSBInstructionToDisassembledInstruction( const char *m = inst.GetMnemonic(target); const char *o = inst.GetOperands(target); - const char *c = inst.GetComment(target); + std::string c = inst.GetComment(target); auto d = inst.GetData(target); std::string bytes; @@ -114,34 +114,30 @@ static DisassembledInstruction ConvertSBInstructionToDisassembledInstruction( DisassembledInstruction disassembled_inst; disassembled_inst.address = inst_addr; - disassembled_inst.instructionBytes = - bytes.size() > 0 ? bytes.substr(0, bytes.size() - 1) : ""; - std::string instruction; - llvm::raw_string_ostream si(instruction); + if (!bytes.empty()) // remove last whitespace +bytes.pop_back(); + disassembled_inst.instructionBytes = std::move(bytes); + + llvm::raw_string_ostream si(disassembled_inst.instruction); + si << llvm::formatv("{0,-7} {1,-25}", m, o); - lldb::SBSymbol symbol = addr.GetSymbol(); // Only add the symbol on the first line of the function. - if (symbol.IsValid() && symbol.GetStartAddress() == addr) { -// If we have a valid symbol, append it as a label prefix for the first -// instruction. This is so you can see the start of a function/callsite -// in the assembly, at the moment VS Code (1.80) does not visualize the -// symbol associated with the assembly instruction. -si << (symbol.GetMangledName() != nullptr ? symbol.GetMangledName() - : symbol.GetName()) - << ": "; + // in the comment section + if (lldb::SBSymbol symbol = addr.GetSymbol(); + symbol.GetStartAddress() == addr) { +const llvm::StringRef sym_display_name = symbol.GetDisplayName(); +c.append(" "); +c.append(sym_display_name); if (resolve_symbols) - disassembled_inst.symbol = symbol.GetDisplayName(); + disassembled_inst.symbol = sym_display_name; } - si << llvm::formatv("{0,7} {1,12}", m, o); - if (c && c[0]) { + if (!c.empty()) { si << " ; " << c; } - disassembled_inst.instruction = std::move(instruction); - protocol::Source source = CreateSource(addr, target); lldb::SBLineEntry line_entry = GetLineEntryForAddress(target, addr); ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] show function name in the instruction comment. (PR #144070)
https://github.com/da-viper closed https://github.com/llvm/llvm-project/pull/144070 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix `ObjectFileMachO` object format when missing version load commands (PR #144177)
https://github.com/dmpots approved this pull request. LGTM. Had one question about the strictness of a test. https://github.com/llvm/llvm-project/pull/144177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix `ObjectFileMachO` object format when missing version load commands (PR #144177)
https://github.com/dmpots edited https://github.com/llvm/llvm-project/pull/144177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix `ObjectFileMachO` object format when missing version load commands (PR #144177)
@@ -94,4 +94,128 @@ TEST_F(ObjectFileMachOTest, IndirectSymbolsInTheSharedCache) { for (size_t i = 0; i < 10; i++) OF->ParseSymtab(symtab); } + +TEST_F(ObjectFileMachOTest, ObjectFormatWithVersionLoadCommand) { + // A Mach-O file of arm64 CPU type and macOS 10.14.0 + const char *yamldata = R"( +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x010C + cpusubtype: 0x + filetype:0x0001 + ncmds: 1 + sizeofcmds: 176 + flags: 0x2000 + reserved:0x +LoadCommands: + - cmd: LC_BUILD_VERSION +cmdsize: 24 +platform:1 +minos: 658944 +sdk: 658944 +ntools: 0 + - cmd: LC_SEGMENT_64 +cmdsize: 152 +segname: __TEXT +vmaddr: 0 +vmsize: 4 +fileoff: 208 +filesize:4 +maxprot: 7 +initprot:7 +nsects: 1 +flags: 0 +Sections: + - sectname:__text +segname: __TEXT +addr:0x +content: 'AABBCCDD' +size:4 +offset: 208 +align: 0 +reloff: 0x +nreloc: 0 +flags: 0x8400 +reserved1: 0x +reserved2: 0x +reserved3: 0x +... +)"; + + // Perform setup. + llvm::Expected file = TestFile::fromYaml(yamldata); + EXPECT_THAT_EXPECTED(file, llvm::Succeeded()); + auto module_sp = std::make_shared(file->moduleSpec()); + ASSERT_NE(module_sp, nullptr); + auto object_file = module_sp->GetObjectFile(); + ASSERT_NE(object_file, nullptr); + + // Verify that the object file is recognized as Mach-O. + ASSERT_EQ(object_file->GetArchitecture().GetTriple().getObjectFormat(), +llvm::Triple::MachO); + + // Verify that the triple string does NOT contain "-macho". + ASSERT_EQ(object_file->GetArchitecture().GetTriple().str(), +"arm64-apple-macosx10.14.0"); +} + +TEST_F(ObjectFileMachOTest, ObjectFormatWithoutVersionLoadCommand) { + // A Mach-O file of arm64 CPU type, without load command LC_BUILD_VERSION. + const char *yamldata = R"( +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x010C + cpusubtype: 0x + filetype:0x0001 + ncmds: 1 + sizeofcmds: 152 + flags: 0x2000 + reserved:0x +LoadCommands: + - cmd: LC_SEGMENT_64 +cmdsize: 152 +segname: __TEXT +vmaddr: 0 +vmsize: 4 +fileoff: 184 +filesize:4 +maxprot: 7 +initprot:7 +nsects: 1 +flags: 0 +Sections: + - sectname:__text +segname: __TEXT +addr:0x +content: 'AABBCCDD' +size:4 +offset: 184 +align: 0 +reloff: 0x +nreloc: 0 +flags: 0x8400 +reserved1: 0x +reserved2: 0x +reserved3: 0x +... +)"; + + // Perform setup. + llvm::Expected file = TestFile::fromYaml(yamldata); + EXPECT_THAT_EXPECTED(file, llvm::Succeeded()); + auto module_sp = std::make_shared(file->moduleSpec()); + ASSERT_NE(module_sp, nullptr); + auto object_file = module_sp->GetObjectFile(); + ASSERT_NE(object_file, nullptr); + + // Verify that the object file is recognized as Mach-O. + ASSERT_EQ(object_file->GetArchitecture().GetTriple().getObjectFormat(), +llvm::Triple::MachO); + + // Verify that the triple string contains "-macho". + ASSERT_EQ(object_file->GetArchitecture().GetTriple().str(), +"arm64-apple--macho"); dmpots wrote: I'm not sure we should check the triple string here. The check in the other test is good because it guards against a behavior that we do not want (having `-macho` appended to the triple string). But in this case I don't think we really care how the triple is printed as long as the `getObjectFormat` returns the correct value. We are not depending on a specific format here so if it changes in the future this test would fail unnecessarily. https://github.com/llvm/llvm-project/pull/144177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix `ObjectFileMachO` object format when missing version load commands (PR #144177)
https://github.com/dmpots commented: There is one early return in this function: https://github.com/llvm/llvm-project/pull/144177/files#diff-1c2c090c5ff772b9b304dbdd4cf45803478f4f33d11d042817fea7358e0cc96bL5167 I wonder if we need to handle this case as well. https://github.com/llvm/llvm-project/pull/144177 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][breakpoint] Grey out disabled breakpoints (PR #91404)
https://github.com/chelcassanova updated https://github.com/llvm/llvm-project/pull/91404 >From 75061e1eb39383dae59ebd3ce3b77d8b550d0ab5 Mon Sep 17 00:00:00 2001 From: Chelsea Cassanova Date: Thu, 9 May 2024 11:08:29 -0700 Subject: [PATCH] [lldb][breakpoint] Grey out disabled breakpoints This commit adds colour settings to the list of breakpoints in order to grey out breakpoints that have been disabled. --- lldb/include/lldb/Core/Debugger.h | 4 +++ lldb/source/Breakpoint/Breakpoint.cpp | 15 +++ lldb/source/Core/CoreProperties.td| 16 lldb/source/Core/Debugger.cpp | 12 + .../API/terminal/TestDisabledBreakpoints.py | 25 +++ 5 files changed, 72 insertions(+) create mode 100644 lldb/test/API/terminal/TestDisabledBreakpoints.py diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index d73aba1e3ce58..2087ef2a11562 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -307,6 +307,10 @@ class Debugger : public std::enable_shared_from_this, llvm::StringRef GetShowProgressAnsiSuffix() const; + llvm::StringRef GetDisabledAnsiPrefix() const; + + llvm::StringRef GetDisabledAnsiSuffix() const; + bool GetUseAutosuggestion() const; llvm::StringRef GetAutosuggestionAnsiPrefix() const; diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp index 337c1a4ac401f..c2d3f4d235548 100644 --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -15,6 +15,7 @@ #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Breakpoint/BreakpointResolverFileLine.h" #include "lldb/Core/Address.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/SearchFilter.h" @@ -26,6 +27,7 @@ #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -838,6 +840,13 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_locations) { assert(s != nullptr); + // Grey out any disabled breakpoints in the list of breakpoints. +const bool highlight_disabled = !IsEnabled() && s->AsRawOstream().colors_enabled(); + if (highlight_disabled) + s->Printf("%s", ansi::FormatAnsiTerminalCodes( + GetTarget().GetDebugger().GetDisabledAnsiPrefix()) + .c_str()); + if (!m_kind_description.empty()) { if (level == eDescriptionLevelBrief) { s->PutCString(GetBreakpointKind()); @@ -934,6 +943,12 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level, } s->IndentLess(); } + + // Reset the colors back to normal if they were previously greyed out. + if (highlight_disabled) +s->Printf("%s", ansi::FormatAnsiTerminalCodes( +GetTarget().GetDebugger().GetDisabledAnsiSuffix()) +.c_str()); } void Breakpoint::GetResolverDescription(Stream *s) { diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index 4d1ea5dfec2eb..53dd333f045c9 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -191,6 +191,22 @@ let Definition = "debugger" in { "${separator}${thread.stop-reason}}{ " "${separator}{${progress.count} }${progress.message}}">, Desc<"The default statusline format string.">; + + def ShowDisabledAnsiPrefix + : Property<"disable-ansi-prefix", "String">, +Global, +DefaultStringValue<"${ansi.faint}">, +Desc<"If something has been disabled in a color-enabled terminal, use " + "the ANSI terminal code specified immediately before whatever has " + "been disabled.">; + def ShowDisabledAnsiSuffix + : Property<"disable-ansi-suffix", "String">, +Global, +DefaultStringValue<"${ansi.normal}">, +Desc<"When somehing has been disabled in a color-enabled terminal, use " + "the ANSI terminal code specified immediately after whatever has " + "been disabled.">; + def UseSourceCache: Property<"use-source-cache", "Boolean">, Global, DefaultTrue, diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 81037d3def811..c9935f2d745fa 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -510,6 +510,18 @@ llvm::StringRef Debugger::GetSeparator() const { idx, g_debugger_properties[idx].default_cstr_value); } +llvm::StringRef Debugger::GetDisabledAnsiPrefix() const { + const uint32_t idx = ePropertyShowDisabledAnsiPrefix; + return GetPropertyAtIndexAs( + idx, g_debugger
[Lldb-commits] [lldb] [lldb] move XcodeSDK's sysroot into a separate class (PR #144396)
https://github.com/charles-zablit created https://github.com/llvm/llvm-project/pull/144396 This PR introduces a new class (`XcodeSDKPath`) which holds both an `XcodeSDK` and a `sysroot` for that SDK. This motivation for this refactor is to eventually implement `GetSDKPathFromDebugInfo` on `PlatformWindows`. >From 0d773d07856aeb5434d748f439a2a1c00361ed20 Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Mon, 16 Jun 2025 17:54:44 +0100 Subject: [PATCH] [lldb] move XcodeSDK's sysroot into a separate class --- lldb/include/lldb/Core/Module.h | 1 + lldb/include/lldb/Symbol/SymbolFile.h | 2 +- lldb/include/lldb/Symbol/SymbolFileOnDemand.h | 2 +- lldb/include/lldb/Target/Platform.h | 13 ++--- lldb/include/lldb/Utility/XcodeSDK.h | 7 --- lldb/include/lldb/Utility/XcodeSDKPath.h | 48 +++ .../Clang/ClangExpressionParser.cpp | 2 +- .../Platform/MacOSX/PlatformDarwin.cpp| 23 - .../Plugins/Platform/MacOSX/PlatformDarwin.h | 5 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 4 +- .../SymbolFile/DWARF/SymbolFileDWARF.h| 2 +- .../DWARF/SymbolFileDWARFDebugMap.cpp | 2 +- .../DWARF/SymbolFileDWARFDebugMap.h | 2 +- lldb/source/Symbol/SymbolFileOnDemand.cpp | 6 +-- lldb/source/Utility/CMakeLists.txt| 1 + lldb/source/Utility/XcodeSDK.cpp | 6 --- lldb/source/Utility/XcodeSDKPath.cpp | 29 +++ .../SymbolFile/DWARF/XcodeSDKModuleTests.cpp | 2 +- lldb/unittests/Utility/XcodeSDKTest.cpp | 27 ++- 19 files changed, 128 insertions(+), 56 deletions(-) create mode 100644 lldb/include/lldb/Utility/XcodeSDKPath.h create mode 100644 lldb/source/Utility/XcodeSDKPath.cpp diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h index 8bb55c95773bc..6bbc950effe44 100644 --- a/lldb/include/lldb/Core/Module.h +++ b/lldb/include/lldb/Core/Module.h @@ -23,6 +23,7 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/UUID.h" #include "lldb/Utility/XcodeSDK.h" +#include "lldb/Utility/XcodeSDKPath.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 75c7f230ddf3d..e660acc66f495 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -148,7 +148,7 @@ class SymbolFile : public PluginInterface { virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0; /// Return the Xcode SDK comp_unit was compiled against. - virtual XcodeSDK ParseXcodeSDK(CompileUnit &comp_unit) { return {}; } + virtual XcodeSDKPath ParseXcodeSDK(CompileUnit &comp_unit) { return {}; } /// This function exists because SymbolFileDWARFDebugMap may extra compile /// units which aren't exposed as "real" compile units. In every other diff --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h index ba4a7f09afeaa..1035b58838e9a 100644 --- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h +++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h @@ -65,7 +65,7 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile { lldb::LanguageType ParseLanguage(lldb_private::CompileUnit &comp_unit) override; - lldb_private::XcodeSDK + lldb_private::XcodeSDKPath ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override; void InitializeObject() override; diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index 35ffdabf907e7..8a44291a770b3 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -28,7 +28,7 @@ #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/Timeout.h" #include "lldb/Utility/UserIDResolver.h" -#include "lldb/Utility/XcodeSDK.h" +#include "lldb/Utility/XcodeSDKPath.h" #include "lldb/lldb-private-forward.h" #include "lldb/lldb-public.h" @@ -442,16 +442,16 @@ class Platform : public PluginInterface { /// Search each CU associated with the specified 'module' for /// the SDK paths the CUs were compiled against. In the presence /// of different SDKs, we try to pick the most appropriate one - /// using \ref XcodeSDK::Merge. + /// using \ref XcodeSDKPath::Merge. /// /// \param[in] module Module whose debug-info CUs to parse for /// which SDK they were compiled against. /// - /// \returns If successful, returns a pair of a parsed XcodeSDK + /// \returns If successful, returns a pair of a parsed XcodeSDKPath /// object and a boolean that is 'true' if we encountered /// a conflicting combination of SDKs when parsing the CUs /// (e.g., a public and internal SDK). - virtual llvm::Expected> + virtual llvm::Expected> GetSDKPathFromDebugInfo(Module &module) { return llvm::createStringError(
[Lldb-commits] [lldb] [lldb-dap] Fix source references (PR #144364)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Ebuka Ezike (da-viper) Changes The [protocol](https://microsoft.github.io/debug-adapter-protocol//specification.html#Types_Source) expects that `sourceReference` be less than `(2^31)-1`, but we currently represent memory address as source reference, this can be truncated either when sending through json or by the client. Instead, generate new source references based on the memory address. Make the `CreateSource` function return an optional source. I passed the `create_reference` function to `CreateSource` to avoid the cyclic dependency of `ProtocolUtils` with `DAP` --- Patch is 22.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/144364.diff 16 Files Affected: - (modified) lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py (+7-7) - (modified) lldb/tools/lldb-dap/Breakpoint.cpp (+5-2) - (modified) lldb/tools/lldb-dap/DAP.cpp (+19) - (modified) lldb/tools/lldb-dap/DAP.h (+6-1) - (modified) lldb/tools/lldb-dap/Handler/DisassembleRequestHandler.cpp (+10-6) - (modified) lldb/tools/lldb-dap/Handler/LocationsRequestHandler.cpp (+20-2) - (modified) lldb/tools/lldb-dap/Handler/SourceRequestHandler.cpp (+20-12) - (modified) lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp (+1-1) - (modified) lldb/tools/lldb-dap/JSONUtils.cpp (+8-4) - (modified) lldb/tools/lldb-dap/JSONUtils.h (+4-1) - (modified) lldb/tools/lldb-dap/Protocol/ProtocolRequests.h (+1-1) - (modified) lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp (+1-1) - (modified) lldb/tools/lldb-dap/Protocol/ProtocolTypes.h (+2-1) - (modified) lldb/tools/lldb-dap/ProtocolUtils.cpp (+32-19) - (modified) lldb/tools/lldb-dap/ProtocolUtils.h (+9-4) - (modified) lldb/tools/lldb-dap/SourceBreakpoint.cpp (+7-1) ``diff diff --git a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py index 8bccc2bcf4156..674bfe4199b4a 100644 --- a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py +++ b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py @@ -67,19 +67,19 @@ def test_break_on_invalid_source_reference(self): "Invalid sourceReference.", ) -# Verify that setting a breakpoint on a source reference without a symbol also fails +# Verify that setting a breakpoint on a source reference that is not created fails response = self.dap_server.request_setBreakpoints( -Source(source_reference=0), [1] +Source(source_reference=200), [1] ) self.assertIsNotNone(response) breakpoints = response["body"]["breakpoints"] self.assertEqual(len(breakpoints), 1) -breakpoint = breakpoints[0] +break_point = breakpoints[0] self.assertFalse( -breakpoint["verified"], "Expected breakpoint to not be verified" +break_point["verified"], "Expected breakpoint to not be verified" ) -self.assertIn("message", breakpoint, "Expected message to be present") +self.assertIn("message", break_point, "Expected message to be present") self.assertEqual( -breakpoint["message"], -"Breakpoints in assembly without a valid symbol are not supported yet.", +break_point["message"], +"Invalid sourceReference.", ) diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp b/lldb/tools/lldb-dap/Breakpoint.cpp index ef5646c4c3d16..e1b073405ebb2 100644 --- a/lldb/tools/lldb-dap/Breakpoint.cpp +++ b/lldb/tools/lldb-dap/Breakpoint.cpp @@ -64,8 +64,11 @@ protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() { "0x" + llvm::utohexstr(bp_addr.GetLoadAddress(m_bp.GetTarget())); breakpoint.instructionReference = formatted_addr; -auto source = CreateSource(bp_addr, m_dap.target); -if (!IsAssemblySource(source)) { +std::optional source = +CreateSource(bp_addr, m_dap.target, [this](lldb::addr_t addr) { + return m_dap.CreateSourceReference(addr); +}); +if (source && !IsAssemblySource(*source)) { auto line_entry = bp_addr.GetLineEntry(); const auto line = line_entry.GetLine(); if (line != LLDB_INVALID_LINE_NUMBER) diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index 9fe8227cd2d6f..56bb5903080dc 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -510,6 +510,25 @@ DAP::SendFormattedOutput(OutputType o, const char *format, ...) { o, llvm::StringRef(buffer, std::min(actual_length, sizeof(buffer; } +int32_t DAP::CreateSourceReference(lldb::addr_t address) { + auto iter = llvm::find(source_references, address); + if (iter != source_references.end()) +return std::distance(source_references.begin(), iter) + 1; + + source_references
[Lldb-commits] [lldb] [lldb-dap] Fix source references (PR #144364)
https://github.com/da-viper edited https://github.com/llvm/llvm-project/pull/144364 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Fix source references (PR #144364)
https://github.com/da-viper created https://github.com/llvm/llvm-project/pull/144364 The [protocol](https://microsoft.github.io/debug-adapter-protocol//specification.html#Types_Source) expects that `sourceReference` be less than `(2^31)-1`, but we currently represent memory address as source reference, this can be truncated either when sending through json or by the client. Instead, generate new source references based on the memory address. Make the `CreateSource` function return an optional source. I passed the `create_reference` function to `CreateSource` to avoid the cyclic dependency of `ProtocolUtils.cpp` with `Dap.cpp` >From 80f7d8b3ffd48a94414374518c022ba682fb7be1 Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Mon, 16 Jun 2025 11:00:05 +0100 Subject: [PATCH] [lldb-dap] Fix source references The protocol expects that `sourceReference` be less than `(2^31)-1`, but we currently represent memory address as source reference, this can be truncated either when sending through json or by the client. Instead, generate new source references based on the memory address. Make the `CreateSource` function return an optional source. --- .../TestDAP_breakpointAssembly.py | 14 ++--- lldb/tools/lldb-dap/Breakpoint.cpp| 7 ++- lldb/tools/lldb-dap/DAP.cpp | 19 +++ lldb/tools/lldb-dap/DAP.h | 7 ++- .../Handler/DisassembleRequestHandler.cpp | 16 +++--- .../Handler/LocationsRequestHandler.cpp | 22 +++- .../lldb-dap/Handler/SourceRequestHandler.cpp | 32 +++- .../Handler/StackTraceRequestHandler.cpp | 2 +- lldb/tools/lldb-dap/JSONUtils.cpp | 12 +++-- lldb/tools/lldb-dap/JSONUtils.h | 5 +- .../lldb-dap/Protocol/ProtocolRequests.h | 2 +- .../tools/lldb-dap/Protocol/ProtocolTypes.cpp | 2 +- lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 3 +- lldb/tools/lldb-dap/ProtocolUtils.cpp | 51 --- lldb/tools/lldb-dap/ProtocolUtils.h | 13 +++-- lldb/tools/lldb-dap/SourceBreakpoint.cpp | 8 ++- 16 files changed, 152 insertions(+), 63 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py index 8bccc2bcf4156..674bfe4199b4a 100644 --- a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py +++ b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py @@ -67,19 +67,19 @@ def test_break_on_invalid_source_reference(self): "Invalid sourceReference.", ) -# Verify that setting a breakpoint on a source reference without a symbol also fails +# Verify that setting a breakpoint on a source reference that is not created fails response = self.dap_server.request_setBreakpoints( -Source(source_reference=0), [1] +Source(source_reference=200), [1] ) self.assertIsNotNone(response) breakpoints = response["body"]["breakpoints"] self.assertEqual(len(breakpoints), 1) -breakpoint = breakpoints[0] +break_point = breakpoints[0] self.assertFalse( -breakpoint["verified"], "Expected breakpoint to not be verified" +break_point["verified"], "Expected breakpoint to not be verified" ) -self.assertIn("message", breakpoint, "Expected message to be present") +self.assertIn("message", break_point, "Expected message to be present") self.assertEqual( -breakpoint["message"], -"Breakpoints in assembly without a valid symbol are not supported yet.", +break_point["message"], +"Invalid sourceReference.", ) diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp b/lldb/tools/lldb-dap/Breakpoint.cpp index ef5646c4c3d16..e1b073405ebb2 100644 --- a/lldb/tools/lldb-dap/Breakpoint.cpp +++ b/lldb/tools/lldb-dap/Breakpoint.cpp @@ -64,8 +64,11 @@ protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() { "0x" + llvm::utohexstr(bp_addr.GetLoadAddress(m_bp.GetTarget())); breakpoint.instructionReference = formatted_addr; -auto source = CreateSource(bp_addr, m_dap.target); -if (!IsAssemblySource(source)) { +std::optional source = +CreateSource(bp_addr, m_dap.target, [this](lldb::addr_t addr) { + return m_dap.CreateSourceReference(addr); +}); +if (source && !IsAssemblySource(*source)) { auto line_entry = bp_addr.GetLineEntry(); const auto line = line_entry.GetLine(); if (line != LLDB_INVALID_LINE_NUMBER) diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index 9fe8227cd2d6f..56bb5903080dc 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -510,6 +510,25 @@ DAP::SendFormattedOutput(OutputType o, const char *format, ...) { o, llvm::StringRef
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -10,17 +10,117 @@ import subprocess import signal import sys +from dataclasses import dataclass import threading import time -from typing import Any, Optional, Union, BinaryIO, TextIO +from typing import ( +IO, +Any, +Callable, +Dict, +List, +Optional, +Tuple, +TypeGuard, +TypeVar, +TypedDict, +Union, +BinaryIO, +TextIO, +Literal, +cast, +) ## DAP type references -Event = dict[str, Any] -Request = dict[str, Any] -Response = dict[str, Any] + +T = TypeVar("T") + + +class Event(TypedDict): +type: Literal["event"] +seq: Literal[0] da-viper wrote: the sequest should be an`int` instead. Currently we are not writing the sequence number. https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Consolidate C++ string buffer summaries (PR #144258)
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/144258 >From 6e0f22122c1c08d64b0e3b74a7a08d2177249d03 Mon Sep 17 00:00:00 2001 From: Nerixyz Date: Sun, 15 Jun 2025 12:23:27 +0200 Subject: [PATCH] [LLDB] Consolidate C++ string buffer summaries --- .../Language/CPlusPlus/CxxStringTypes.cpp | 105 ++--- .../Language/CPlusPlus/CxxStringTypes.h | 30 .../Plugins/Language/CPlusPlus/LibCxx.cpp | 147 -- .../string/TestDataFormatterLibcxxString.py | 8 +- .../TestDataFormatterLibcxxStringView.py | 8 +- 5 files changed, 152 insertions(+), 146 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index fc17b76804d9f..4e7569cd8a388 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -116,15 +116,7 @@ bool lldb_private::formatters::WCharStringSummaryProvider( return false; // Get a wchar_t basic type from the current type system - CompilerType wchar_compiler_type = - valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); - - if (!wchar_compiler_type) -return false; - - // Safe to pass nullptr for exe_scope here. - std::optional size = - llvm::expectedToOptional(wchar_compiler_type.GetBitSize(nullptr)); + std::optional size = GetWCharByteSize(*valobj.GetTargetSP()); if (!size) return false; const uint32_t wchar_size = *size; @@ -136,13 +128,13 @@ bool lldb_private::formatters::WCharStringSummaryProvider( options.SetPrefixToken("L"); switch (wchar_size) { - case 8: + case 1: return StringPrinter::ReadStringAndDumpToStream( options); - case 16: + case 2: return StringPrinter::ReadStringAndDumpToStream( options); - case 32: + case 4: return StringPrinter::ReadStringAndDumpToStream( options); default: @@ -177,15 +169,7 @@ bool lldb_private::formatters::WCharSummaryProvider( return false; // Get a wchar_t basic type from the current type system - CompilerType wchar_compiler_type = - valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); - - if (!wchar_compiler_type) -return false; - -// Safe to pass nullptr for exe_scope here. - std::optional size = - llvm::expectedToOptional(wchar_compiler_type.GetBitSize(nullptr)); + std::optional size = GetWCharByteSize(*valobj.GetTargetSP()); if (!size) return false; const uint32_t wchar_size = *size; @@ -199,13 +183,13 @@ bool lldb_private::formatters::WCharSummaryProvider( options.SetBinaryZeroIsTerminator(false); switch (wchar_size) { - case 8: + case 1: return StringPrinter::ReadBufferAndDumpToStream( options); - case 16: + case 2: return StringPrinter::ReadBufferAndDumpToStream( options); - case 32: + case 4: return StringPrinter::ReadBufferAndDumpToStream( options); default: @@ -214,3 +198,76 @@ bool lldb_private::formatters::WCharSummaryProvider( } return true; } + +std::optional +lldb_private::formatters::GetWCharByteSize(Target &target) { + TypeSystemClangSP scratch_ts_sp = + ScratchTypeSystemClang::GetForTarget(target); + if (!scratch_ts_sp) +return {}; + + return llvm::expectedToOptional( + scratch_ts_sp->GetBasicType(lldb::eBasicTypeWChar).GetByteSize(nullptr)); +} + +template +bool lldb_private::formatters::StringBufferSummaryProvider( +Stream &stream, const TypeSummaryOptions &summary_options, +lldb::ValueObjectSP location_sp, uint64_t size, std::string prefix_token) { + + if (size == 0) { +stream.PutCString(prefix_token); +stream.PutCString("\"\""); +return true; + } + + if (!location_sp) +return false; + + StringPrinter::ReadBufferAndDumpToStreamOptions options(*location_sp); + + if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { +const auto max_size = +location_sp->GetTargetSP()->GetMaximumSizeOfStringSummary(); +if (size > max_size) { + size = max_size; + options.SetIsTruncated(true); +} + } + + { +DataExtractor extractor; +const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); +if (bytes_read < size) + return false; + +options.SetData(std::move(extractor)); + } + options.SetStream(&stream); + if (prefix_token.empty()) +options.SetPrefixToken(nullptr); + else +options.SetPrefixToken(prefix_token); + options.SetQuote('"'); + options.SetSourceSize(size); + options.SetBinaryZeroIsTerminator(false); + return StringPrinter::ReadBufferAndDumpToStream(options); +} + +// explicit instantiations for all string element types +template bool +lldb_private::formatters::StringBufferSummaryProvider( +Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t, +std::string); +template bool +lldb_private::formatte
[Lldb-commits] [lldb] [lldb-dap] show function name in the instruction comment. (PR #144070)
ashgti wrote: Ah, ok, if is already like this in other places, SGTM https://github.com/llvm/llvm-project/pull/144070 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add DWARFExpressionEntry and GetExpressionEntryAtAddress() to … (PR #144238)
@@ -53,6 +53,27 @@ bool DWARFExpressionList::ContainsAddress(lldb::addr_t func_load_addr, return GetExpressionAtAddress(func_load_addr, addr) != nullptr; } +llvm::Expected +DWARFExpressionList::GetExpressionEntryAtAddress(lldb::addr_t func_load_addr, + lldb::addr_t load_addr) const { + if (const DWARFExpression *expr = GetAlwaysValidExpr()) { +return DWARFExpressionEntry{0, LLDB_INVALID_ADDRESS, expr}; + } + + if (func_load_addr == LLDB_INVALID_ADDRESS) +func_load_addr = m_func_file_addr; + + addr_t addr = load_addr - func_load_addr + m_func_file_addr; + uint32_t index = m_exprs.FindEntryIndexThatContains(addr); + if (index == UINT32_MAX) { +return llvm::createStringError(llvm::inconvertibleErrorCode(), + "No DWARF expression found for address 0x%llx", addr); adrian-prantl wrote: Generally using Expected is desirable, especially if there is actionable information in the error message (and information that only this function can provide). Lookups are borderline cases. If it's expected during normal operation that client will call this API and the lookup fails, then I would return a `std::optional` instead. The client can turn this into a more targeted error message if needed. In short — I would return a std::optional here. https://github.com/llvm/llvm-project/pull/144238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add DWARFExpressionEntry and GetExpressionEntryAtAddress() to … (PR #144238)
@@ -59,6 +59,18 @@ class DWARFExpressionList { lldb::addr_t GetFuncFileAddress() { return m_func_file_addr; } + /// Represents an entry in the DWARFExpressionList with all needed metadata + struct DWARFExpressionEntry { +lldb::addr_t base; +lldb::addr_t end; adrian-prantl wrote: Note that if you do want to use Address, there is already an AddressRange class. https://github.com/llvm/llvm-project/pull/144238 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][breakpoint] Grey out disabled breakpoints (PR #91404)
https://github.com/chelcassanova updated https://github.com/llvm/llvm-project/pull/91404 >From 8608a949e6579f9ee69961ceabf8158a6b91b208 Mon Sep 17 00:00:00 2001 From: Chelsea Cassanova Date: Thu, 9 May 2024 11:08:29 -0700 Subject: [PATCH 1/3] [lldb][breakpoint] Grey out disabled breakpoints This commit adds colour settings to the list of breakpoints in order to grey out breakpoints that have been disabled. --- lldb/include/lldb/Core/Debugger.h | 4 +++ lldb/source/Breakpoint/Breakpoint.cpp | 15 +++ lldb/source/Core/CoreProperties.td| 16 lldb/source/Core/Debugger.cpp | 12 + .../API/terminal/TestDisabledBreakpoints.py | 25 +++ 5 files changed, 72 insertions(+) create mode 100644 lldb/test/API/terminal/TestDisabledBreakpoints.py diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 0595125b1813d..0fd4545e8425d 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -302,6 +302,10 @@ class Debugger : public std::enable_shared_from_this, llvm::StringRef GetShowProgressAnsiSuffix() const; + llvm::StringRef GetDisabledAnsiPrefix() const; + + llvm::StringRef GetDisabledAnsiSuffix() const; + bool GetUseAutosuggestion() const; llvm::StringRef GetAutosuggestionAnsiPrefix() const; diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp index 337c1a4ac401f..d48520b02f9e0 100644 --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -15,6 +15,7 @@ #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Breakpoint/BreakpointResolverFileLine.h" #include "lldb/Core/Address.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/SearchFilter.h" @@ -26,6 +27,7 @@ #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -838,6 +840,13 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_locations) { assert(s != nullptr); + // Grey out any disabled breakpoints in the list of breakpoints. + if (!IsEnabled()) +if (s->AsRawOstream().colors_enabled()) + s->Printf("%s", ansi::FormatAnsiTerminalCodes( + GetTarget().GetDebugger().GetDisabledAnsiPrefix()) + .c_str()); + if (!m_kind_description.empty()) { if (level == eDescriptionLevelBrief) { s->PutCString(GetBreakpointKind()); @@ -934,6 +943,12 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level, } s->IndentLess(); } + + // Reset the colors back to normal if they were previously greyed out. + if (s->AsRawOstream().colors_enabled()) +s->Printf("%s", ansi::FormatAnsiTerminalCodes( +GetTarget().GetDebugger().GetDisabledAnsiSuffix()) +.c_str()); } void Breakpoint::GetResolverDescription(Stream *s) { diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index a1a4e994c3b9c..20421360e93c4 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -191,6 +191,22 @@ let Definition = "debugger" in { "${separator}${thread.stop-reason}}{ " "${separator}{${progress.count} }${progress.message}}">, Desc<"The default statusline format string.">; + + def ShowDisabledAnsiPrefix + : Property<"disable-ansi-prefix", "String">, +Global, +DefaultStringValue<"${ansi.faint}">, +Desc<"If something has been disabled in a color-enabled terminal, use " + "the ANSI terminal code specified immediately before whatever has " + "been disabled.">; + def ShowDisabledAnsiSuffix + : Property<"disable-ansi-suffix", "String">, +Global, +DefaultStringValue<"${ansi.normal}">, +Desc<"When somehing has been disabled in a color-enabled terminal, use " + "the ANSI terminal code specified immediately after whatever has " + "been disabled.">; + def UseSourceCache: Property<"use-source-cache", "Boolean">, Global, DefaultTrue, diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 1a0723a2f3b3f..b195798482601 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -510,6 +510,18 @@ llvm::StringRef Debugger::GetSeparator() const { idx, g_debugger_properties[idx].default_cstr_value); } +llvm::StringRef Debugger::GetDisabledAnsiPrefix() const { + const uint32_t idx = ePropertyShowDisabledAnsiPrefix; + return GetPropertyAtIndexAs( + idx, g_debugger_properties[idx].default_cstr_v
[Lldb-commits] [lldb] [lldb-dap] show function name in the instruction comment. (PR #144070)
https://github.com/ashgti approved this pull request. https://github.com/llvm/llvm-project/pull/144070 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add supported languages in package.json (PR #144414)
https://github.com/JDevlieghere approved this pull request. Thanks! https://github.com/llvm/llvm-project/pull/144414 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
https://github.com/ashgti updated https://github.com/llvm/llvm-project/pull/143818 >From ab4b987aec591491d3805af41c7127ff6698fe0e Mon Sep 17 00:00:00 2001 From: John Harrison Date: Wed, 11 Jun 2025 15:57:16 -0700 Subject: [PATCH 1/4] [lldb-dap] Refactring DebugCommunication to improve test consistency. In DebugCommunication, we currently are using 2 thread to drive lldb-dap. At the moment, they make an attempt at only synchronizing the `recv_packets` between the reader thread and the main test thread. Other stateful properties of the debug session are not guarded by any mutexs. To mitigate this, I am moving any state updates to the main thread inside the `_recv_packet` method to ensure that between calls to `_recv_packet` the state does not change out from under us in a test. This does mean the precise timing of events has changed slightly as a result and I've updated the existing tests that fail for me locally with this new behavior. I think this should result in overall more predictable behavior, even if the test is slow due to the host workload or architecture differences. --- .../test/tools/lldb-dap/dap_server.py | 839 +++--- .../test/tools/lldb-dap/lldbdap_testcase.py | 79 +- .../breakpoint/TestDAP_setBreakpoints.py | 5 +- .../tools/lldb-dap/cancel/TestDAP_cancel.py | 10 +- .../tools/lldb-dap/launch/TestDAP_launch.py | 12 +- .../tools/lldb-dap/module/TestDAP_module.py | 2 +- .../tools/lldb-dap/output/TestDAP_output.py | 4 +- 7 files changed, 568 insertions(+), 383 deletions(-) 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 9786678aa53f9..20a1b4480df6d 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 @@ -10,17 +10,117 @@ import subprocess import signal import sys +from dataclasses import dataclass import threading import time -from typing import Any, Optional, Union, BinaryIO, TextIO +from typing import ( +IO, +Any, +Callable, +Dict, +List, +Optional, +Tuple, +TypeGuard, +TypeVar, +TypedDict, +Union, +BinaryIO, +TextIO, +Literal, +cast, +) ## DAP type references -Event = dict[str, Any] -Request = dict[str, Any] -Response = dict[str, Any] + +T = TypeVar("T") + + +class Event(TypedDict): +type: Literal["event"] +seq: Literal[0] +event: str +body: Optional[dict] + + +class Request(TypedDict): +type: Literal["request"] +seq: int +command: str +arguments: Optional[dict] + + +class Response(TypedDict): +type: Literal["response"] +seq: Literal[0] +request_seq: int +success: bool +command: str +message: Optional[str] +body: Optional[dict] + + ProtocolMessage = Union[Event, Request, Response] +class AttachOrLaunchArguments(TypedDict, total=False): +stopOnEntry: bool +disableASLR: bool +disableSTDIO: bool +enableAutoVariableSummaries: bool +displayExtendedBacktrace: bool +enableSyntheticChildDebugging: bool +initCommands: List[str] +preRunCommands: List[str] +postRunCommands: List[str] +stopCommands: List[str] +exitCommands: List[str] +terminateCommands: List[str] +sourceMap: Union[List[Tuple[str, str]], Dict[str, str]] +sourcePath: str +debuggerRoot: str +commandEscapePrefix: str +customFrameFormat: str +customThreadFormat: str + + +class LaunchArguments(AttachOrLaunchArguments, total=False): +program: str +args: List[str] +cwd: str +env: Dict[str, str] +shellExpandArguments: bool +runInTerminal: bool +launchCommands: List[str] + + +class AttachArguments(AttachOrLaunchArguments, total=False): +program: str +pid: int +waitFor: bool +attachCommands: List[str] +coreFile: str +gdbRemotePort: int +gdbRemoteHostname: str + + +class BreakpiontData(TypedDict, total=False): +column: int +condition: str +hitCondition: str +logMessage: str +mode: str + + +class SourceBreakpoint(BreakpiontData): +line: int + + +class Breakpoint(TypedDict, total=False): +id: int +verified: bool + + def dump_memory(base_addr, data, num_per_line, outfile): data_len = len(data) hex_string = binascii.hexlify(data) @@ -58,7 +158,9 @@ def dump_memory(base_addr, data, num_per_line, outfile): outfile.write("\n") -def read_packet(f, verbose=False, trace_file=None): +def read_packet( +f: IO[bytes], verbose: bool = False, trace_file: Optional[IO[str]] = None +) -> Optional[ProtocolMessage]: """Decode a JSON packet that starts with the content length and is followed by the JSON bytes from a file 'f'. Returns None on EOF. """ @@ -76,26 +178,22 @@ def read_packet(f, verbose=False, trace_file=None): if verbose: print('length: "%u"' %
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -10,17 +10,117 @@ import subprocess import signal import sys +from dataclasses import dataclass import threading import time -from typing import Any, Optional, Union, BinaryIO, TextIO +from typing import ( +IO, +Any, +Callable, +Dict, +List, +Optional, +Tuple, +TypeGuard, +TypeVar, +TypedDict, +Union, +BinaryIO, +TextIO, +Literal, +cast, +) ## DAP type references -Event = dict[str, Any] -Request = dict[str, Any] -Response = dict[str, Any] + +T = TypeVar("T") + + +class Event(TypedDict): +type: Literal["event"] +seq: Literal[0] +event: str +body: Optional[dict] + + +class Request(TypedDict): +type: Literal["request"] +seq: int +command: str +arguments: Optional[dict] + + +class Response(TypedDict): +type: Literal["response"] +seq: Literal[0] ashgti wrote: Done. https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -10,17 +10,117 @@ import subprocess import signal import sys +from dataclasses import dataclass import threading import time -from typing import Any, Optional, Union, BinaryIO, TextIO +from typing import ( +IO, +Any, +Callable, +Dict, +List, +Optional, +Tuple, +TypeGuard, +TypeVar, +TypedDict, +Union, +BinaryIO, +TextIO, +Literal, +cast, +) ## DAP type references -Event = dict[str, Any] -Request = dict[str, Any] -Response = dict[str, Any] + +T = TypeVar("T") + + +class Event(TypedDict): +type: Literal["event"] +seq: Literal[0] ashgti wrote: Done. https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Implement priority system for symbol locator plugin (PR #144406)
https://github.com/GeorgeHuyubo created https://github.com/llvm/llvm-project/pull/144406 In the context if locate_module callback is registered and debuginfod is enabled. If debuginfod symbol locator is called first then we are double downloading the debuginfo file through locate module callback and debuginfod. To fix this, we want to a way to define the priority of a plugin, so that we can adjust the order of each plugin gets called at runtime. ``` (lldb)settings set plugin.symbol-locator.debuginfod.priority 1 (lldb) image list ... [ 4] 581109F0-138B-AD5B-2E0B-1EB3E5174353-632286CF 0x7f977c60 /tmp/symbol_cache/581109f0138bad5b2e0b1eb3e5174353632286cf/libcrypto.so.1.1 /home/hyubo/.cache/llvm-debuginfod/client/llvmcache-581109f0138bad5b2e0b1eb3e5174353632286cf-libcrypto.so.1.1.debuginfo ``` Debuginfod plugin is prioritized ``` (lldb)settings set plugin.symbol-locator.debuginfod.priority 3 (lldb) image list ... [ 4] 581109F0-138B-AD5B-2E0B-1EB3E5174353-632286CF 0x7f977c60 /tmp/symbol_cache/581109f0138bad5b2e0b1eb3e5174353632286cf/libcrypto.so.1.1 /tmp/symbol_cache/581109f0138bad5b2e0b1eb3e5174353632286cf/libcrypto.so.1.1.debuginfo ``` Default plugin is prioritized, local debuginfo is used. >From a60a15ee140a261c9902cdbfaa9811fe87c291fc Mon Sep 17 00:00:00 2001 From: George Hu Date: Mon, 16 Jun 2025 10:57:26 -0700 Subject: [PATCH] [lldb] Implement priority system for symbol locator plugin --- lldb/include/lldb/Core/PluginManager.h| 3 +- lldb/include/lldb/Symbol/SymbolLocator.h | 3 + lldb/include/lldb/lldb-private-interfaces.h | 1 + lldb/source/Core/PluginManager.cpp| 60 --- .../Debuginfod/SymbolLocatorDebuginfod.cpp| 20 ++- .../SymbolLocatorDebuginfodProperties.td | 3 + 6 files changed, 80 insertions(+), 10 deletions(-) diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index e7b169103..021f90f54abff 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -431,7 +431,8 @@ class PluginManager { SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file = nullptr, SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle = nullptr, - DebuggerInitializeCallback debugger_init_callback = nullptr); + DebuggerInitializeCallback debugger_init_callback = nullptr, + SymbolLocatorGetPriority get_priority_callback = nullptr); static bool UnregisterPlugin(SymbolLocatorCreateInstance create_callback); diff --git a/lldb/include/lldb/Symbol/SymbolLocator.h b/lldb/include/lldb/Symbol/SymbolLocator.h index 8d2f26b3d0cca..0eb9d34cb1cc6 100644 --- a/lldb/include/lldb/Symbol/SymbolLocator.h +++ b/lldb/include/lldb/Symbol/SymbolLocator.h @@ -14,6 +14,9 @@ namespace lldb_private { +// Default priority for symbol locator plugins +static constexpr uint32_t kDefaultSymbolLocatorPriority = 2; + class SymbolLocator : public PluginInterface { public: SymbolLocator() = default; diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index d366dbd1d7832..0fe59e28adaa6 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -100,6 +100,7 @@ typedef std::optional (*SymbolLocatorLocateExecutableSymbolFile)( typedef bool (*SymbolLocatorDownloadObjectAndSymbolFile)( ModuleSpec &module_spec, Status &error, bool force_lookup, bool copy_executable); +typedef uint64_t (*SymbolLocatorGetPriority)(); using BreakpointHitCallback = std::function; diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index 5d44434033c55..fedfd3f1e7b6f 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -13,6 +13,7 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Symbol/SaveCoreOptions.h" +#include "lldb/Symbol/SymbolLocator.h" #include "lldb/Target/Process.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" @@ -25,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -323,6 +325,29 @@ template class PluginInstances { return enabled_instances; } + // Return a priority queue of all enabled instances, ordered by priority + // (lower priority values = higher priority in queue) + template + std::priority_queue, + std::function> + GetPriorityQueue(PriorityGetter get_priority) { +// Create comparator that orders by priority (lower values = higher +// priority) +auto comparator = [get_priority](const Instance &a, const Instance &b) { + return get_priority(a) > get_priority(b); // Reverse for min-heap behavior +}; + +std::priority_queue, +std::function> +pq(comparator); + +for (const auto &instance : m_in
[Lldb-commits] [lldb] [lldb-dap] Add supported languages in package.json (PR #144414)
https://github.com/DrSergei created https://github.com/llvm/llvm-project/pull/144414 This patch fixes the [problem](https://github.com/llvm/llvm-project/issues/144239). It was caused by missing supported languages list in `package.json`. VSCode uses `guessDebugger` [function](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts#L344) to find supported debuggers based on supported languages in case of opened file. It uses `interestedInLanguage` [function](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/debug/common/debugger.ts#L171) to do that, so we should provide list of supported languages. Also, fixed typo in `fortran`. Before:  After:  >From da1a74c3586286125f6be36bab9780d41169da39 Mon Sep 17 00:00:00 2001 From: Druzhkov Sergei Date: Mon, 16 Jun 2025 22:10:48 +0300 Subject: [PATCH] [lldb-dap] Add supported languages in package.json --- lldb/tools/lldb-dap/package.json | 18 +- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json index 0f51c4f935e33..b150dee792c34 100644 --- a/lldb/tools/lldb-dap/package.json +++ b/lldb/tools/lldb-dap/package.json @@ -290,7 +290,7 @@ "language": "d" }, { -"language": "fortan" +"language": "fortran" }, { "language": "fortran-modern" @@ -318,6 +318,22 @@ { "type": "lldb-dap", "label": "LLDB DAP Debugger", +"languages": [ + "ada", + "arm", + "c", + "cpp", + "crystal", + "d", + "fortran", + "fortran-modern", + "nim", + "objective-c", + "objectpascal", + "pascal", + "rust", + "swift" +], "configurationAttributes": { "launch": { "required": [ ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add supported languages in package.json (PR #144414)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/144414 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -189,262 +298,322 @@ def _read_packet_thread(self): while not done: packet = read_packet(self.recv, trace_file=self.trace_file) # `packet` will be `None` on EOF. We want to pass it down to -# handle_recv_packet anyway so the main thread can handle unexpected -# termination of lldb-dap and stop waiting for new packets. +# handle_recv_packet anyway so the main thread can handle +# unexpected termination of lldb-dap and stop waiting for new +# packets. done = not self._handle_recv_packet(packet) finally: dump_dap_log(self.log_file) -def get_modules(self): -module_list = self.request_modules()["body"]["modules"] -modules = {} -for module in module_list: -modules[module["name"]] = module -return modules +def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: +"""Handles an incoming packet. -def get_output(self, category, timeout=0.0, clear=True): -self.output_condition.acquire() -output = None -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -elif timeout != 0.0: -self.output_condition.wait(timeout) -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -self.output_condition.release() -return output +Called by the read thread that is waiting for all incoming packets +to store the incoming packet in "self._recv_packets" in a thread safe +way. This function will then signal the "self._recv_condition" to +indicate a new packet is available. -def collect_output(self, category, timeout_secs, pattern, clear=True): -end_time = time.time() + timeout_secs -collected_output = "" -while end_time > time.time(): -output = self.get_output(category, timeout=0.25, clear=clear) -if output: -collected_output += output -if pattern is not None and pattern in output: -break -return collected_output if collected_output else None - -def _enqueue_recv_packet(self, packet: Optional[ProtocolMessage]): -self.recv_condition.acquire() -self.recv_packets.append(packet) -self.recv_condition.notify() -self.recv_condition.release() +Args: +packet: A new packet to store. -def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: -"""Called by the read thread that is waiting for all incoming packets -to store the incoming packet in "self.recv_packets" in a thread safe -way. This function will then signal the "self.recv_condition" to -indicate a new packet is available. Returns True if the caller -should keep calling this function for more packets. +Returns: +True if the caller should keep calling this function for more +packets. """ -# If EOF, notify the read thread by enqueuing a None. -if not packet: -self._enqueue_recv_packet(None) -return False - -# Check the packet to see if is an event packet -keepGoing = True -packet_type = packet["type"] -if packet_type == "event": -event = packet["event"] -body = None -if "body" in packet: -body = packet["body"] -# Handle the event packet and cache information from these packets -# as they come in -if event == "output": -# Store any output we receive so clients can retrieve it later. -category = body["category"] -output = body["output"] -self.output_condition.acquire() -if category in self.output: -self.output[category] += output -else: -self.output[category] = output -self.output_condition.notify() -self.output_condition.release() -# no need to add 'output' event packets to our packets list -return keepGoing -elif event == "initialized": -self.initialized = True -elif event == "process": -# When a new process is attached or launched, remember the -# details that are available in the body of the event -self.process_event_body = body -elif event == "exited": -# Process exited, mark the status to indicate the process is not -# alive. -self.exit_status = body["exitCode"] -
[Lldb-commits] [lldb] [lldb-dap][test] fix not supported error. (PR #144419)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Ebuka Ezike (da-viper) Changes Fixes #144072 buildbot error. --- Full diff: https://github.com/llvm/llvm-project/pull/144419.diff 1 Files Affected: - (modified) lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py (+7-1) ``diff diff --git a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py index 51ccf2ccbdcad..05adfb3e342b0 100644 --- a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py +++ b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py @@ -90,7 +90,13 @@ def test_supported_capability_x86_arch(self): len(breakpoint_ids), len(bp_lines), "expect correct number of breakpoints" ) self.continue_to_breakpoints(breakpoint_ids) -is_supported = self.dap_server.get_capability("supportsStepInTargetsRequest") + +try: +is_supported = self.dap_server.get_capability( +"supportsStepInTargetsRequest" +) +except dap_server.NotSupportedError: +is_supported = False self.assertEqual( is_supported, `` https://github.com/llvm/llvm-project/pull/144419 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap][test] fix not supported error. (PR #144419)
https://github.com/JDevlieghere approved this pull request. https://github.com/llvm/llvm-project/pull/144419 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
https://github.com/ashgti updated https://github.com/llvm/llvm-project/pull/143818 >From ab4b987aec591491d3805af41c7127ff6698fe0e Mon Sep 17 00:00:00 2001 From: John Harrison Date: Wed, 11 Jun 2025 15:57:16 -0700 Subject: [PATCH 1/5] [lldb-dap] Refactring DebugCommunication to improve test consistency. In DebugCommunication, we currently are using 2 thread to drive lldb-dap. At the moment, they make an attempt at only synchronizing the `recv_packets` between the reader thread and the main test thread. Other stateful properties of the debug session are not guarded by any mutexs. To mitigate this, I am moving any state updates to the main thread inside the `_recv_packet` method to ensure that between calls to `_recv_packet` the state does not change out from under us in a test. This does mean the precise timing of events has changed slightly as a result and I've updated the existing tests that fail for me locally with this new behavior. I think this should result in overall more predictable behavior, even if the test is slow due to the host workload or architecture differences. --- .../test/tools/lldb-dap/dap_server.py | 839 +++--- .../test/tools/lldb-dap/lldbdap_testcase.py | 79 +- .../breakpoint/TestDAP_setBreakpoints.py | 5 +- .../tools/lldb-dap/cancel/TestDAP_cancel.py | 10 +- .../tools/lldb-dap/launch/TestDAP_launch.py | 12 +- .../tools/lldb-dap/module/TestDAP_module.py | 2 +- .../tools/lldb-dap/output/TestDAP_output.py | 4 +- 7 files changed, 568 insertions(+), 383 deletions(-) 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 9786678aa53f9..20a1b4480df6d 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 @@ -10,17 +10,117 @@ import subprocess import signal import sys +from dataclasses import dataclass import threading import time -from typing import Any, Optional, Union, BinaryIO, TextIO +from typing import ( +IO, +Any, +Callable, +Dict, +List, +Optional, +Tuple, +TypeGuard, +TypeVar, +TypedDict, +Union, +BinaryIO, +TextIO, +Literal, +cast, +) ## DAP type references -Event = dict[str, Any] -Request = dict[str, Any] -Response = dict[str, Any] + +T = TypeVar("T") + + +class Event(TypedDict): +type: Literal["event"] +seq: Literal[0] +event: str +body: Optional[dict] + + +class Request(TypedDict): +type: Literal["request"] +seq: int +command: str +arguments: Optional[dict] + + +class Response(TypedDict): +type: Literal["response"] +seq: Literal[0] +request_seq: int +success: bool +command: str +message: Optional[str] +body: Optional[dict] + + ProtocolMessage = Union[Event, Request, Response] +class AttachOrLaunchArguments(TypedDict, total=False): +stopOnEntry: bool +disableASLR: bool +disableSTDIO: bool +enableAutoVariableSummaries: bool +displayExtendedBacktrace: bool +enableSyntheticChildDebugging: bool +initCommands: List[str] +preRunCommands: List[str] +postRunCommands: List[str] +stopCommands: List[str] +exitCommands: List[str] +terminateCommands: List[str] +sourceMap: Union[List[Tuple[str, str]], Dict[str, str]] +sourcePath: str +debuggerRoot: str +commandEscapePrefix: str +customFrameFormat: str +customThreadFormat: str + + +class LaunchArguments(AttachOrLaunchArguments, total=False): +program: str +args: List[str] +cwd: str +env: Dict[str, str] +shellExpandArguments: bool +runInTerminal: bool +launchCommands: List[str] + + +class AttachArguments(AttachOrLaunchArguments, total=False): +program: str +pid: int +waitFor: bool +attachCommands: List[str] +coreFile: str +gdbRemotePort: int +gdbRemoteHostname: str + + +class BreakpiontData(TypedDict, total=False): +column: int +condition: str +hitCondition: str +logMessage: str +mode: str + + +class SourceBreakpoint(BreakpiontData): +line: int + + +class Breakpoint(TypedDict, total=False): +id: int +verified: bool + + def dump_memory(base_addr, data, num_per_line, outfile): data_len = len(data) hex_string = binascii.hexlify(data) @@ -58,7 +158,9 @@ def dump_memory(base_addr, data, num_per_line, outfile): outfile.write("\n") -def read_packet(f, verbose=False, trace_file=None): +def read_packet( +f: IO[bytes], verbose: bool = False, trace_file: Optional[IO[str]] = None +) -> Optional[ProtocolMessage]: """Decode a JSON packet that starts with the content length and is followed by the JSON bytes from a file 'f'. Returns None on EOF. """ @@ -76,26 +178,22 @@ def read_packet(f, verbose=False, trace_file=None): if verbose: print('length: "%u"' %
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
@@ -0,0 +1,131 @@ +//===- Protocol.h -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLDB_PLUGINS_PROTOCOL_MCP_PROTOCOL_H +#define LLDB_PLUGINS_PROTOCOL_MCP_PROTOCOL_H + +#include "llvm/Support/JSON.h" +#include +#include + +namespace lldb_private::mcp::protocol { + +static llvm::StringLiteral kProtocolVersion = "2025-03-26"; + +struct Request { + uint64_t id = 0; + std::string method; + std::optional params; +}; + +llvm::json::Value toJSON(const Request &); +bool fromJSON(const llvm::json::Value &, Request &, llvm::json::Path); + +struct Error { + int64_t code = 0; + std::string message; + std::optional data; +}; + +llvm::json::Value toJSON(const Error &); +bool fromJSON(const llvm::json::Value &, Error &, llvm::json::Path); + +struct ProtocolError { + uint64_t id = 0; + Error error; +}; + +llvm::json::Value toJSON(const ProtocolError &); +bool fromJSON(const llvm::json::Value &, ProtocolError &, llvm::json::Path); + +struct Response { + uint64_t id = 0; + std::optional result; + std::optional error; +}; + +llvm::json::Value toJSON(const Response &); +bool fromJSON(const llvm::json::Value &, Response &, llvm::json::Path); + +struct Notification { + std::string method; + std::optional params; +}; + +llvm::json::Value toJSON(const Notification &); +bool fromJSON(const llvm::json::Value &, Notification &, llvm::json::Path); + +struct ToolCapability { + bool listChanged = false; +}; JDevlieghere wrote: Yup, I think that's something we could support. Completion was added in the latest revision of the spec and to support older tools I've settled on the previous revision for now, but this might be a good motivator to move to the next version. https://github.com/llvm/llvm-project/pull/143628 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -71,31 +173,27 @@ def read_packet(f, verbose=False, trace_file=None): if line.startswith(prefix): # Decode length of JSON bytes if verbose: -print('content: "%s"' % (line)) +print(f"content: {line}") ashgti wrote: I dropped these, your right about this not being used anywhere. https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -189,262 +298,322 @@ def _read_packet_thread(self): while not done: packet = read_packet(self.recv, trace_file=self.trace_file) # `packet` will be `None` on EOF. We want to pass it down to -# handle_recv_packet anyway so the main thread can handle unexpected -# termination of lldb-dap and stop waiting for new packets. +# handle_recv_packet anyway so the main thread can handle +# unexpected termination of lldb-dap and stop waiting for new +# packets. done = not self._handle_recv_packet(packet) finally: dump_dap_log(self.log_file) -def get_modules(self): -module_list = self.request_modules()["body"]["modules"] -modules = {} -for module in module_list: -modules[module["name"]] = module -return modules +def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: +"""Handles an incoming packet. -def get_output(self, category, timeout=0.0, clear=True): -self.output_condition.acquire() -output = None -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -elif timeout != 0.0: -self.output_condition.wait(timeout) -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -self.output_condition.release() -return output +Called by the read thread that is waiting for all incoming packets +to store the incoming packet in "self._recv_packets" in a thread safe +way. This function will then signal the "self._recv_condition" to +indicate a new packet is available. -def collect_output(self, category, timeout_secs, pattern, clear=True): -end_time = time.time() + timeout_secs -collected_output = "" -while end_time > time.time(): -output = self.get_output(category, timeout=0.25, clear=clear) -if output: -collected_output += output -if pattern is not None and pattern in output: -break -return collected_output if collected_output else None - -def _enqueue_recv_packet(self, packet: Optional[ProtocolMessage]): -self.recv_condition.acquire() -self.recv_packets.append(packet) -self.recv_condition.notify() -self.recv_condition.release() +Args: +packet: A new packet to store. -def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: -"""Called by the read thread that is waiting for all incoming packets -to store the incoming packet in "self.recv_packets" in a thread safe -way. This function will then signal the "self.recv_condition" to -indicate a new packet is available. Returns True if the caller -should keep calling this function for more packets. +Returns: +True if the caller should keep calling this function for more +packets. """ -# If EOF, notify the read thread by enqueuing a None. -if not packet: -self._enqueue_recv_packet(None) -return False - -# Check the packet to see if is an event packet -keepGoing = True -packet_type = packet["type"] -if packet_type == "event": -event = packet["event"] -body = None -if "body" in packet: -body = packet["body"] -# Handle the event packet and cache information from these packets -# as they come in -if event == "output": -# Store any output we receive so clients can retrieve it later. -category = body["category"] -output = body["output"] -self.output_condition.acquire() -if category in self.output: -self.output[category] += output -else: -self.output[category] = output -self.output_condition.notify() -self.output_condition.release() -# no need to add 'output' event packets to our packets list -return keepGoing -elif event == "initialized": -self.initialized = True -elif event == "process": -# When a new process is attached or launched, remember the -# details that are available in the body of the event -self.process_event_body = body -elif event == "exited": -# Process exited, mark the status to indicate the process is not -# alive. -self.exit_status = body["exitCode"] -
[Lldb-commits] [lldb] [lldb][RPC] Upstream lldb-rpc-gen tool (PR #138031)
@@ -0,0 +1,535 @@ +//===-- RPCCommon.cpp -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "RPCCommon.h" + +#include "clang/AST/AST.h" +#include "clang/AST/Mangle.h" +#include "clang/Lex/Lexer.h" + +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang; + +// We intentionally do not generate some classes because they are currently +// inconvenient, they aren't really used by most consumers, or we're not sure +// why they exist. +static constexpr llvm::StringRef DisallowedClasses[] = { +"SBCommunication", // What is this used for? +"SBInputReader",// What is this used for? +"SBCommandPluginInterface", // This is hard to support, we can do it if +// really needed though. +"SBCommand", // There's nothing too difficult about this one, but many of + // its methods take a SBCommandPluginInterface pointer so + // there's no reason to support this. +}; + +// We intentionally avoid generating certain methods either because they are +// difficult to support correctly or they aren't really used much from C++. +// FIXME: We should be able to annotate these methods instead of maintaining a +// list in the generator itself. +static constexpr llvm::StringRef DisallowedMethods[] = { +// The threading functionality in SBHostOS is deprecated and thus we do not +// generate them. It would be ideal to add the annotations to the methods +// and then support not generating deprecated methods. However, without +// annotations the generator generates most things correctly. This one is +// problematic because it returns a pointer to an "opaque" structure +// (thread_t) that is not `void *`, so special casing it is more effort than +// it's worth. +"_ZN4lldb8SBHostOS10ThreadJoinEP17_opaque_pthread_tPPvPNS_7SBErrorE", +"_ZN4lldb8SBHostOS12ThreadCancelEP17_opaque_pthread_tPNS_7SBErrorE", +"_ZN4lldb8SBHostOS12ThreadCreateEPKcPFPvS3_ES3_PNS_7SBErrorE", +"_ZN4lldb8SBHostOS12ThreadDetachEP17_opaque_pthread_tPNS_7SBErrorE", +"_ZN4lldb8SBHostOS13ThreadCreatedEPKc", +}; + +static constexpr llvm::StringRef ClassesWithoutDefaultCtor[] = { +"SBHostOS", +"SBReproducer", +}; + +static constexpr llvm::StringRef ClassesWithoutCopyOperations[] = { +"SBHostOS", +"SBReproducer", +"SBStream", +"SBProgress", +}; + +static constexpr llvm::StringRef MethodsWithPointerPlusLen[] = { bulbazord wrote: I'm generally in favor of annotation the API for RPC purposes. The RPC code generator needs to make assumptions about the usage of the API based on the method signatures and it can go sideways pretty easily (as you and I have seen internally). I'd rather lldb-rpc-gen not silently drop methods because it can't prove that it knows the semantics of the parameters. David's point is a good one. I think documenting the known failure conditions and how to fix them should help folks with little knowledge or understanding of LLDBRPC. At least, having it on documentation gives us something to point them to. https://github.com/llvm/llvm-project/pull/138031 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap][test] fix not supported error. (PR #144419)
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/144419 >From 31dc0abff52f4897f83d1405f65bf00ca0aa81cb Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Mon, 16 Jun 2025 20:33:34 +0100 Subject: [PATCH] [lldb-dap][test] fix not supported error. --- .../tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py index 51ccf2ccbdcad..03b79a805d341 100644 --- a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py +++ b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py @@ -112,7 +112,13 @@ def test_supported_capability_other_archs(self): len(breakpoint_ids), len(bp_lines), "expect correct number of breakpoints" ) self.continue_to_breakpoints(breakpoint_ids) -is_supported = self.dap_server.get_capability("supportsStepInTargetsRequest") + +try: +is_supported = self.dap_server.get_capability( +"supportsStepInTargetsRequest" +) +except dap_server.NotSupportedError: +is_supported = False self.assertEqual( is_supported, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][RPC] Upstream lldb-rpc-gen tool (PR #138031)
bulbazord wrote: > @bulbazord I have a auggestion for this patch. I want to have the minimum > CMake necessary to let the tool build. To accomplish this, I want to take out > all code in this tool that relates to the server/client code, leaving the > code that generates the byproducts. I'd then shift the server code in > `lldb-rpc-gen.cpp` to the patch that's already up for the server emitter and > the client code for the patch for the client emitters. In effect: > > * This patch would have all RPCCommon code for lldb-rpc-gen > * `lldb-rpc-gen.cpp` will be stripped down to the code that generates the > byproducts (namely the class names, method names and skipped methods file) > * As mentioned above, the code in lldb-rpc-gen.cpp that relates to generating > the server code would move to the patch that's up for the server emitters. > * A test could be put up to just check that the byproducts files have been > emitted in their expected locations. > > I'd love to get your thoughts on this. I say go for it. It would be a lot easier to review and you can introduce the server-side and client library generators incrementally. https://github.com/llvm/llvm-project/pull/138031 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Explicitly use python for version fixup (PR #144217)
https://github.com/bulbazord approved this pull request. https://github.com/llvm/llvm-project/pull/144217 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/143628 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
@@ -0,0 +1,72 @@ +//===- Tool.cpp ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Tool.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandReturnObject.h" + +using namespace lldb_private::mcp; +using namespace llvm; + +Tool::Tool(std::string name, std::string description) +: m_name(std::move(name)), m_description(std::move(description)) {} + +protocol::ToolDefinition Tool::GetDefinition() const { + protocol::ToolDefinition definition; + definition.name = m_name; + definition.description.emplace(m_description); + + if (std::optional input_schema = GetSchema()) +definition.inputSchema = *input_schema; + + if (m_annotations) +definition.annotations = m_annotations; + + return definition; +} + +LLDBCommandTool::LLDBCommandTool(std::string name, std::string description, + Debugger &debugger) +: Tool(std::move(name), std::move(description)), m_debugger(debugger) {} + +protocol::TextResult LLDBCommandTool::Call(const llvm::json::Value &args) { + std::string arguments; + if (const json::Object *args_obj = args.getAsObject()) { +if (const json::Value *s = args_obj->get("arguments")) { + arguments = s->getAsString().value_or(""); +} + } + + CommandReturnObject result(/*colors=*/false); + m_debugger.GetCommandInterpreter().HandleCommand(arguments.c_str(), labath wrote: I know a team which tries to do that, but I'm not sure they realize how easily workaroundable that is (`command alias print_help quit; print_help`). Given what I've read about AI, I'm fairly certain it could come up with this sequence if it sets its mind to it. To make this reliable, I think we'd at least need to resolve all aliases down to core commands. https://github.com/llvm/llvm-project/pull/143628 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
https://github.com/labath commented: A very lightweight review. I'm focusing on the low-level details. I have no clue about this AI stuff. https://github.com/llvm/llvm-project/pull/143628 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Consolidate C++ string buffer summaries (PR #144258)
https://github.com/Michael137 commented: Moving the code seems fine, pending the two review comments https://github.com/llvm/llvm-project/pull/144258 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Consolidate C++ string buffer summaries (PR #144258)
@@ -199,13 +183,13 @@ bool lldb_private::formatters::WCharSummaryProvider( options.SetBinaryZeroIsTerminator(false); switch (wchar_size) { - case 8: + case 1: Nerixyz wrote: No, this wasn't wrong. It used the _bit size_ before, and the libc++ summary used the _byte size_. I'm not sure which is better (I suppose 8 bits/byte is true for all targets supported by LLDB). This reminds me of another difference: The `*CharSummaryProvider`s used `valobj.GetCompilerType().GetBasicTypeFromAST()` and the libc++ formatters used `ScratchTypeSystemClang::GetBasicType()`. Is there a big difference between them, and is one preferred over the other? https://github.com/llvm/llvm-project/pull/144258 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -10,17 +10,117 @@ import subprocess import signal import sys +from dataclasses import dataclass import threading import time -from typing import Any, Optional, Union, BinaryIO, TextIO +from typing import ( +IO, +Any, +Callable, +Dict, +List, +Optional, +Tuple, +TypeGuard, +TypeVar, +TypedDict, +Union, +BinaryIO, +TextIO, +Literal, +cast, +) ## DAP type references -Event = dict[str, Any] -Request = dict[str, Any] -Response = dict[str, Any] + +T = TypeVar("T") + + +class Event(TypedDict): +type: Literal["event"] +seq: Literal[0] +event: str +body: Optional[dict] + + +class Request(TypedDict): +type: Literal["request"] +seq: int +command: str +arguments: Optional[dict] + + +class Response(TypedDict): +type: Literal["response"] +seq: Literal[0] +request_seq: int +success: bool +command: str +message: Optional[str] +body: Optional[dict] + + ProtocolMessage = Union[Event, Request, Response] +class AttachOrLaunchArguments(TypedDict, total=False): +stopOnEntry: bool +disableASLR: bool +disableSTDIO: bool +enableAutoVariableSummaries: bool +displayExtendedBacktrace: bool +enableSyntheticChildDebugging: bool +initCommands: List[str] +preRunCommands: List[str] +postRunCommands: List[str] +stopCommands: List[str] +exitCommands: List[str] +terminateCommands: List[str] +sourceMap: Union[List[Tuple[str, str]], Dict[str, str]] +sourcePath: str +debuggerRoot: str +commandEscapePrefix: str +customFrameFormat: str +customThreadFormat: str + + +class LaunchArguments(AttachOrLaunchArguments, total=False): +program: str +args: List[str] +cwd: str +env: Dict[str, str] +shellExpandArguments: bool +runInTerminal: bool +launchCommands: List[str] + + +class AttachArguments(AttachOrLaunchArguments, total=False): +program: str +pid: int +waitFor: bool +attachCommands: List[str] +coreFile: str +gdbRemotePort: int +gdbRemoteHostname: str + + +class BreakpiontData(TypedDict, total=False): da-viper wrote: ```suggestion class BreakpointData(TypedDict, total=False): ``` https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -10,17 +10,117 @@ import subprocess import signal import sys +from dataclasses import dataclass import threading import time -from typing import Any, Optional, Union, BinaryIO, TextIO +from typing import ( +IO, +Any, +Callable, +Dict, +List, +Optional, +Tuple, +TypeGuard, +TypeVar, +TypedDict, +Union, +BinaryIO, +TextIO, +Literal, +cast, +) ## DAP type references -Event = dict[str, Any] -Request = dict[str, Any] -Response = dict[str, Any] + +T = TypeVar("T") + + +class Event(TypedDict): +type: Literal["event"] +seq: Literal[0] +event: str +body: Optional[dict] + + +class Request(TypedDict): +type: Literal["request"] +seq: int +command: str +arguments: Optional[dict] + + +class Response(TypedDict): +type: Literal["response"] +seq: Literal[0] da-viper wrote: same as the event seq https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -189,262 +298,322 @@ def _read_packet_thread(self): while not done: packet = read_packet(self.recv, trace_file=self.trace_file) # `packet` will be `None` on EOF. We want to pass it down to -# handle_recv_packet anyway so the main thread can handle unexpected -# termination of lldb-dap and stop waiting for new packets. +# handle_recv_packet anyway so the main thread can handle +# unexpected termination of lldb-dap and stop waiting for new +# packets. done = not self._handle_recv_packet(packet) finally: dump_dap_log(self.log_file) -def get_modules(self): -module_list = self.request_modules()["body"]["modules"] -modules = {} -for module in module_list: -modules[module["name"]] = module -return modules +def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: +"""Handles an incoming packet. -def get_output(self, category, timeout=0.0, clear=True): -self.output_condition.acquire() -output = None -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -elif timeout != 0.0: -self.output_condition.wait(timeout) -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -self.output_condition.release() -return output +Called by the read thread that is waiting for all incoming packets +to store the incoming packet in "self._recv_packets" in a thread safe +way. This function will then signal the "self._recv_condition" to +indicate a new packet is available. -def collect_output(self, category, timeout_secs, pattern, clear=True): -end_time = time.time() + timeout_secs -collected_output = "" -while end_time > time.time(): -output = self.get_output(category, timeout=0.25, clear=clear) -if output: -collected_output += output -if pattern is not None and pattern in output: -break -return collected_output if collected_output else None - -def _enqueue_recv_packet(self, packet: Optional[ProtocolMessage]): -self.recv_condition.acquire() -self.recv_packets.append(packet) -self.recv_condition.notify() -self.recv_condition.release() +Args: +packet: A new packet to store. -def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: -"""Called by the read thread that is waiting for all incoming packets -to store the incoming packet in "self.recv_packets" in a thread safe -way. This function will then signal the "self.recv_condition" to -indicate a new packet is available. Returns True if the caller -should keep calling this function for more packets. +Returns: +True if the caller should keep calling this function for more +packets. """ -# If EOF, notify the read thread by enqueuing a None. -if not packet: -self._enqueue_recv_packet(None) -return False - -# Check the packet to see if is an event packet -keepGoing = True -packet_type = packet["type"] -if packet_type == "event": -event = packet["event"] -body = None -if "body" in packet: -body = packet["body"] -# Handle the event packet and cache information from these packets -# as they come in -if event == "output": -# Store any output we receive so clients can retrieve it later. -category = body["category"] -output = body["output"] -self.output_condition.acquire() -if category in self.output: -self.output[category] += output -else: -self.output[category] = output -self.output_condition.notify() -self.output_condition.release() -# no need to add 'output' event packets to our packets list -return keepGoing -elif event == "initialized": -self.initialized = True -elif event == "process": -# When a new process is attached or launched, remember the -# details that are available in the body of the event -self.process_event_body = body -elif event == "exited": -# Process exited, mark the status to indicate the process is not -# alive. -self.exit_status = body["exitCode"] -
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -189,262 +298,322 @@ def _read_packet_thread(self): while not done: packet = read_packet(self.recv, trace_file=self.trace_file) # `packet` will be `None` on EOF. We want to pass it down to -# handle_recv_packet anyway so the main thread can handle unexpected -# termination of lldb-dap and stop waiting for new packets. +# handle_recv_packet anyway so the main thread can handle +# unexpected termination of lldb-dap and stop waiting for new +# packets. done = not self._handle_recv_packet(packet) finally: dump_dap_log(self.log_file) -def get_modules(self): -module_list = self.request_modules()["body"]["modules"] -modules = {} -for module in module_list: -modules[module["name"]] = module -return modules +def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: +"""Handles an incoming packet. -def get_output(self, category, timeout=0.0, clear=True): -self.output_condition.acquire() -output = None -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -elif timeout != 0.0: -self.output_condition.wait(timeout) -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -self.output_condition.release() -return output +Called by the read thread that is waiting for all incoming packets +to store the incoming packet in "self._recv_packets" in a thread safe +way. This function will then signal the "self._recv_condition" to +indicate a new packet is available. -def collect_output(self, category, timeout_secs, pattern, clear=True): -end_time = time.time() + timeout_secs -collected_output = "" -while end_time > time.time(): -output = self.get_output(category, timeout=0.25, clear=clear) -if output: -collected_output += output -if pattern is not None and pattern in output: -break -return collected_output if collected_output else None - -def _enqueue_recv_packet(self, packet: Optional[ProtocolMessage]): -self.recv_condition.acquire() -self.recv_packets.append(packet) -self.recv_condition.notify() -self.recv_condition.release() +Args: +packet: A new packet to store. -def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: -"""Called by the read thread that is waiting for all incoming packets -to store the incoming packet in "self.recv_packets" in a thread safe -way. This function will then signal the "self.recv_condition" to -indicate a new packet is available. Returns True if the caller -should keep calling this function for more packets. +Returns: +True if the caller should keep calling this function for more +packets. """ -# If EOF, notify the read thread by enqueuing a None. -if not packet: -self._enqueue_recv_packet(None) -return False - -# Check the packet to see if is an event packet -keepGoing = True -packet_type = packet["type"] -if packet_type == "event": -event = packet["event"] -body = None -if "body" in packet: -body = packet["body"] -# Handle the event packet and cache information from these packets -# as they come in -if event == "output": -# Store any output we receive so clients can retrieve it later. -category = body["category"] -output = body["output"] -self.output_condition.acquire() -if category in self.output: -self.output[category] += output -else: -self.output[category] = output -self.output_condition.notify() -self.output_condition.release() -# no need to add 'output' event packets to our packets list -return keepGoing -elif event == "initialized": -self.initialized = True -elif event == "process": -# When a new process is attached or launched, remember the -# details that are available in the body of the event -self.process_event_body = body -elif event == "exited": -# Process exited, mark the status to indicate the process is not -# alive. -self.exit_status = body["exitCode"] -
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -71,31 +173,27 @@ def read_packet(f, verbose=False, trace_file=None): if line.startswith(prefix): # Decode length of JSON bytes if verbose: -print('content: "%s"' % (line)) +print(f"content: {line}") da-viper wrote: i don't think is prints to anywhere since we are in test. we could remove the verbose option completely as no function is using it. https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -152,35 +246,50 @@ def __init__( self.log_file = log_file self.send = send self.recv = recv -self.recv_packets: list[Optional[ProtocolMessage]] = [] -self.recv_condition = threading.Condition() -self.recv_thread = threading.Thread(target=self._read_packet_thread) -self.process_event_body = None -self.exit_status: Optional[int] = None -self.capabilities: dict[str, Any] = {} -self.progress_events: list[Event] = [] -self.reverse_requests = [] -self.sequence = 1 -self.threads = None -self.thread_stop_reasons = {} -self.recv_thread.start() -self.output_condition = threading.Condition() -self.output: dict[str, list[str]] = {} -self.configuration_done_sent = False -self.initialized = False -self.frame_scopes = {} +# Packets that have been received and processed but have not yet been +# requested by a test case. +self._pending_packets: List[Optional[ProtocolMessage]] = [] +# Recieved packets that have not yet been processed. da-viper wrote: ```suggestion # Received packets that have not yet been processed. ``` https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
https://github.com/ashgti updated https://github.com/llvm/llvm-project/pull/143818 >From ab4b987aec591491d3805af41c7127ff6698fe0e Mon Sep 17 00:00:00 2001 From: John Harrison Date: Wed, 11 Jun 2025 15:57:16 -0700 Subject: [PATCH 1/3] [lldb-dap] Refactring DebugCommunication to improve test consistency. In DebugCommunication, we currently are using 2 thread to drive lldb-dap. At the moment, they make an attempt at only synchronizing the `recv_packets` between the reader thread and the main test thread. Other stateful properties of the debug session are not guarded by any mutexs. To mitigate this, I am moving any state updates to the main thread inside the `_recv_packet` method to ensure that between calls to `_recv_packet` the state does not change out from under us in a test. This does mean the precise timing of events has changed slightly as a result and I've updated the existing tests that fail for me locally with this new behavior. I think this should result in overall more predictable behavior, even if the test is slow due to the host workload or architecture differences. --- .../test/tools/lldb-dap/dap_server.py | 839 +++--- .../test/tools/lldb-dap/lldbdap_testcase.py | 79 +- .../breakpoint/TestDAP_setBreakpoints.py | 5 +- .../tools/lldb-dap/cancel/TestDAP_cancel.py | 10 +- .../tools/lldb-dap/launch/TestDAP_launch.py | 12 +- .../tools/lldb-dap/module/TestDAP_module.py | 2 +- .../tools/lldb-dap/output/TestDAP_output.py | 4 +- 7 files changed, 568 insertions(+), 383 deletions(-) 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 9786678aa53f9..20a1b4480df6d 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 @@ -10,17 +10,117 @@ import subprocess import signal import sys +from dataclasses import dataclass import threading import time -from typing import Any, Optional, Union, BinaryIO, TextIO +from typing import ( +IO, +Any, +Callable, +Dict, +List, +Optional, +Tuple, +TypeGuard, +TypeVar, +TypedDict, +Union, +BinaryIO, +TextIO, +Literal, +cast, +) ## DAP type references -Event = dict[str, Any] -Request = dict[str, Any] -Response = dict[str, Any] + +T = TypeVar("T") + + +class Event(TypedDict): +type: Literal["event"] +seq: Literal[0] +event: str +body: Optional[dict] + + +class Request(TypedDict): +type: Literal["request"] +seq: int +command: str +arguments: Optional[dict] + + +class Response(TypedDict): +type: Literal["response"] +seq: Literal[0] +request_seq: int +success: bool +command: str +message: Optional[str] +body: Optional[dict] + + ProtocolMessage = Union[Event, Request, Response] +class AttachOrLaunchArguments(TypedDict, total=False): +stopOnEntry: bool +disableASLR: bool +disableSTDIO: bool +enableAutoVariableSummaries: bool +displayExtendedBacktrace: bool +enableSyntheticChildDebugging: bool +initCommands: List[str] +preRunCommands: List[str] +postRunCommands: List[str] +stopCommands: List[str] +exitCommands: List[str] +terminateCommands: List[str] +sourceMap: Union[List[Tuple[str, str]], Dict[str, str]] +sourcePath: str +debuggerRoot: str +commandEscapePrefix: str +customFrameFormat: str +customThreadFormat: str + + +class LaunchArguments(AttachOrLaunchArguments, total=False): +program: str +args: List[str] +cwd: str +env: Dict[str, str] +shellExpandArguments: bool +runInTerminal: bool +launchCommands: List[str] + + +class AttachArguments(AttachOrLaunchArguments, total=False): +program: str +pid: int +waitFor: bool +attachCommands: List[str] +coreFile: str +gdbRemotePort: int +gdbRemoteHostname: str + + +class BreakpiontData(TypedDict, total=False): +column: int +condition: str +hitCondition: str +logMessage: str +mode: str + + +class SourceBreakpoint(BreakpiontData): +line: int + + +class Breakpoint(TypedDict, total=False): +id: int +verified: bool + + def dump_memory(base_addr, data, num_per_line, outfile): data_len = len(data) hex_string = binascii.hexlify(data) @@ -58,7 +158,9 @@ def dump_memory(base_addr, data, num_per_line, outfile): outfile.write("\n") -def read_packet(f, verbose=False, trace_file=None): +def read_packet( +f: IO[bytes], verbose: bool = False, trace_file: Optional[IO[str]] = None +) -> Optional[ProtocolMessage]: """Decode a JSON packet that starts with the content length and is followed by the JSON bytes from a file 'f'. Returns None on EOF. """ @@ -76,26 +178,22 @@ def read_packet(f, verbose=False, trace_file=None): if verbose: print('length: "%u"' %
[Lldb-commits] [lldb] [lldb] Fix FindProcessImpl() for iOS simulators (PR #139174)
https://github.com/royitaqi edited https://github.com/llvm/llvm-project/pull/139174 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Explicitly use python for version fixup (PR #144217)
https://github.com/JDevlieghere approved this pull request. https://github.com/llvm/llvm-project/pull/144217 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Creating protocol types for setExceptionBreakpoints. (PR #144153)
https://github.com/JDevlieghere approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/144153 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Use structured types for stepInTargets request (PR #144072)
https://github.com/JDevlieghere approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/144072 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][breakpoint] Grey out disabled breakpoints (PR #91404)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- lldb/include/lldb/Core/Debugger.h lldb/source/Breakpoint/Breakpoint.cpp lldb/source/Core/Debugger.cpp `` View the diff from clang-format here. ``diff diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp index c2d3f4d23..c5cb14b0b 100644 --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -841,11 +841,12 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level, assert(s != nullptr); // Grey out any disabled breakpoints in the list of breakpoints. -const bool highlight_disabled = !IsEnabled() && s->AsRawOstream().colors_enabled(); + const bool highlight_disabled = + !IsEnabled() && s->AsRawOstream().colors_enabled(); if (highlight_disabled) - s->Printf("%s", ansi::FormatAnsiTerminalCodes( - GetTarget().GetDebugger().GetDisabledAnsiPrefix()) - .c_str()); +s->Printf("%s", ansi::FormatAnsiTerminalCodes( +GetTarget().GetDebugger().GetDisabledAnsiPrefix()) +.c_str()); if (!m_kind_description.empty()) { if (level == eDescriptionLevelBrief) { `` https://github.com/llvm/llvm-project/pull/91404 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Use structured types for stepInTargets request (PR #144072)
@@ -582,6 +582,28 @@ llvm::json::Value toJSON(const SteppingGranularity &SG) { llvm_unreachable("unhandled stepping granularity."); } +bool fromJSON(const json::Value &Params, StepInTarget &SIT, json::Path P) { + json::ObjectMapper O(Params, P); + return O && O.map("id", SIT.id) && O.map("label", SIT.label) && + O.map("line", SIT.line) && O.map("column", SIT.column) && + O.map("endLine", SIT.endLine) && O.map("endColumn", SIT.endColumn); ashgti wrote: I think `line`, `column`, `endLine`, `endColumn` are all optional in the spec, so these should be `mapOptional` otherwise you'll get an error if they're not specified. https://github.com/llvm/llvm-project/pull/144072 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Use structured types for stepInTargets request (PR #144072)
https://github.com/ashgti approved this pull request. https://github.com/llvm/llvm-project/pull/144072 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][breakpoint] Grey out disabled breakpoints (PR #91404)
https://github.com/chelcassanova updated https://github.com/llvm/llvm-project/pull/91404 >From 8608a949e6579f9ee69961ceabf8158a6b91b208 Mon Sep 17 00:00:00 2001 From: Chelsea Cassanova Date: Thu, 9 May 2024 11:08:29 -0700 Subject: [PATCH 1/2] [lldb][breakpoint] Grey out disabled breakpoints This commit adds colour settings to the list of breakpoints in order to grey out breakpoints that have been disabled. --- lldb/include/lldb/Core/Debugger.h | 4 +++ lldb/source/Breakpoint/Breakpoint.cpp | 15 +++ lldb/source/Core/CoreProperties.td| 16 lldb/source/Core/Debugger.cpp | 12 + .../API/terminal/TestDisabledBreakpoints.py | 25 +++ 5 files changed, 72 insertions(+) create mode 100644 lldb/test/API/terminal/TestDisabledBreakpoints.py diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 0595125b1813d..0fd4545e8425d 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -302,6 +302,10 @@ class Debugger : public std::enable_shared_from_this, llvm::StringRef GetShowProgressAnsiSuffix() const; + llvm::StringRef GetDisabledAnsiPrefix() const; + + llvm::StringRef GetDisabledAnsiSuffix() const; + bool GetUseAutosuggestion() const; llvm::StringRef GetAutosuggestionAnsiPrefix() const; diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp index 337c1a4ac401f..d48520b02f9e0 100644 --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -15,6 +15,7 @@ #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Breakpoint/BreakpointResolverFileLine.h" #include "lldb/Core/Address.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/SearchFilter.h" @@ -26,6 +27,7 @@ #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -838,6 +840,13 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_locations) { assert(s != nullptr); + // Grey out any disabled breakpoints in the list of breakpoints. + if (!IsEnabled()) +if (s->AsRawOstream().colors_enabled()) + s->Printf("%s", ansi::FormatAnsiTerminalCodes( + GetTarget().GetDebugger().GetDisabledAnsiPrefix()) + .c_str()); + if (!m_kind_description.empty()) { if (level == eDescriptionLevelBrief) { s->PutCString(GetBreakpointKind()); @@ -934,6 +943,12 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level, } s->IndentLess(); } + + // Reset the colors back to normal if they were previously greyed out. + if (s->AsRawOstream().colors_enabled()) +s->Printf("%s", ansi::FormatAnsiTerminalCodes( +GetTarget().GetDebugger().GetDisabledAnsiSuffix()) +.c_str()); } void Breakpoint::GetResolverDescription(Stream *s) { diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index a1a4e994c3b9c..20421360e93c4 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -191,6 +191,22 @@ let Definition = "debugger" in { "${separator}${thread.stop-reason}}{ " "${separator}{${progress.count} }${progress.message}}">, Desc<"The default statusline format string.">; + + def ShowDisabledAnsiPrefix + : Property<"disable-ansi-prefix", "String">, +Global, +DefaultStringValue<"${ansi.faint}">, +Desc<"If something has been disabled in a color-enabled terminal, use " + "the ANSI terminal code specified immediately before whatever has " + "been disabled.">; + def ShowDisabledAnsiSuffix + : Property<"disable-ansi-suffix", "String">, +Global, +DefaultStringValue<"${ansi.normal}">, +Desc<"When somehing has been disabled in a color-enabled terminal, use " + "the ANSI terminal code specified immediately after whatever has " + "been disabled.">; + def UseSourceCache: Property<"use-source-cache", "Boolean">, Global, DefaultTrue, diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 1a0723a2f3b3f..b195798482601 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -510,6 +510,18 @@ llvm::StringRef Debugger::GetSeparator() const { idx, g_debugger_properties[idx].default_cstr_value); } +llvm::StringRef Debugger::GetDisabledAnsiPrefix() const { + const uint32_t idx = ePropertyShowDisabledAnsiPrefix; + return GetPropertyAtIndexAs( + idx, g_debugger_properties[idx].default_cstr_v
[Lldb-commits] [lldb] [lldb][breakpoint] Grey out disabled breakpoints (PR #91404)
@@ -838,6 +840,13 @@ void Breakpoint::GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_locations) { assert(s != nullptr); + // Grey out any disabled breakpoints in the list of breakpoints. + if (!IsEnabled()) +if (s->AsRawOstream().colors_enabled()) chelcassanova wrote: Just updated the patch to add this. https://github.com/llvm/llvm-project/pull/91404 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap][test] fix not supported error. (PR #144419)
da-viper wrote: @JDevlieghere or @ashgti by any chance you have a mac or arm pc to check if this works locally merging ? https://github.com/llvm/llvm-project/pull/144419 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -189,262 +298,322 @@ def _read_packet_thread(self): while not done: packet = read_packet(self.recv, trace_file=self.trace_file) # `packet` will be `None` on EOF. We want to pass it down to -# handle_recv_packet anyway so the main thread can handle unexpected -# termination of lldb-dap and stop waiting for new packets. +# handle_recv_packet anyway so the main thread can handle +# unexpected termination of lldb-dap and stop waiting for new +# packets. done = not self._handle_recv_packet(packet) finally: dump_dap_log(self.log_file) -def get_modules(self): -module_list = self.request_modules()["body"]["modules"] -modules = {} -for module in module_list: -modules[module["name"]] = module -return modules +def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: +"""Handles an incoming packet. -def get_output(self, category, timeout=0.0, clear=True): -self.output_condition.acquire() -output = None -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -elif timeout != 0.0: -self.output_condition.wait(timeout) -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -self.output_condition.release() -return output +Called by the read thread that is waiting for all incoming packets +to store the incoming packet in "self._recv_packets" in a thread safe +way. This function will then signal the "self._recv_condition" to +indicate a new packet is available. -def collect_output(self, category, timeout_secs, pattern, clear=True): -end_time = time.time() + timeout_secs -collected_output = "" -while end_time > time.time(): -output = self.get_output(category, timeout=0.25, clear=clear) -if output: -collected_output += output -if pattern is not None and pattern in output: -break -return collected_output if collected_output else None - -def _enqueue_recv_packet(self, packet: Optional[ProtocolMessage]): -self.recv_condition.acquire() -self.recv_packets.append(packet) -self.recv_condition.notify() -self.recv_condition.release() +Args: +packet: A new packet to store. -def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: -"""Called by the read thread that is waiting for all incoming packets -to store the incoming packet in "self.recv_packets" in a thread safe -way. This function will then signal the "self.recv_condition" to -indicate a new packet is available. Returns True if the caller -should keep calling this function for more packets. +Returns: +True if the caller should keep calling this function for more +packets. """ -# If EOF, notify the read thread by enqueuing a None. -if not packet: -self._enqueue_recv_packet(None) -return False - -# Check the packet to see if is an event packet -keepGoing = True -packet_type = packet["type"] -if packet_type == "event": -event = packet["event"] -body = None -if "body" in packet: -body = packet["body"] -# Handle the event packet and cache information from these packets -# as they come in -if event == "output": -# Store any output we receive so clients can retrieve it later. -category = body["category"] -output = body["output"] -self.output_condition.acquire() -if category in self.output: -self.output[category] += output -else: -self.output[category] = output -self.output_condition.notify() -self.output_condition.release() -# no need to add 'output' event packets to our packets list -return keepGoing -elif event == "initialized": -self.initialized = True -elif event == "process": -# When a new process is attached or launched, remember the -# details that are available in the body of the event -self.process_event_body = body -elif event == "exited": -# Process exited, mark the status to indicate the process is not -# alive. -self.exit_status = body["exitCode"] -
[Lldb-commits] [lldb] [lldb-dap] Fix source references (PR #144364)
@@ -37,10 +37,15 @@ protocol::Source CreateSource(const lldb::SBFileSpec &file); /// \param[in] target /// The target that has the address. /// +/// \param[in] create_reference +/// function used to create a source_reference +/// /// \return -/// A "Source" JSON object that follows the formal JSON +/// An optional "Source" JSON object that follows the formal JSON /// definition outlined by Microsoft. -protocol::Source CreateSource(lldb::SBAddress address, lldb::SBTarget &target); +std::optional +CreateSource(lldb::SBAddress address, lldb::SBTarget &target, + llvm::function_ref create_reference); da-viper wrote: > Should we move this into the DAP? Something like optional > DAP::ResolveSource(SBAddress, SBTarget); that creates or returns a source for > the given address? I am leaning towards this because there may be clients that do not support the optional `source` argument in `SourceRequest` https://github.com/llvm/llvm-project/pull/144364 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add supported languages in package.json (PR #144414)
https://github.com/da-viper approved this pull request. https://github.com/llvm/llvm-project/pull/144414 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add count for number of DWO files loaded in statistics (PR #144424)
https://github.com/qxy11 created https://github.com/llvm/llvm-project/pull/144424 ## Summary A new `totalLoadedDwoFileCount` is added to available statisctics when calling "statistics dump". 1. The counter in SymbolFileDWARF `m_loaded_dwo_file_count` is added, and accessed through the `GetLoadedDwoFileCount()` 2. `m_loaded_dwo_file_count` is incremented through a new protected function `IncrementLoadedDwoFileCount()`, which is called in the constructor of `SymbolFileDWARFDwo` (as opposed to directly incrementing the counter in SymbolFileDwarf to prevent inconsistent updates to the counter in the future). 3. The `GetLoadedDwoFileCount()` API is added to `SymbolFile.h` for access to the DWO count from the symbol files loaded in `Statistics`, which returns 0 by default for all symbol file types except for `SymbolFileDWARF`. ## Testing **Manual Testing** On an internal script that has many DWO files, `statistics dump` was called before and after a `type lookup` command. The `totalLoadedDwoFileCount` increased as expected after the `type lookup`. ``` (lldb) statistics dump { ... "totalLoadedDwoFileCount": 29, } (lldb) type lookup folly::Optional::Storage typedef std::conditional::StorageTriviallyDestructible, folly::Optional::StorageNonTriviallyDestructible>::type typedef std::conditional::StorageTriviallyDestructible, folly::Optional::StorageNonTriviallyDestructible>::type ... (lldb) statistics dump { ... "totalLoadedDwoFileCount": 2160, } ``` **Unit test** Added a unit test that builds new "third.cpp" and "baz.cpp" files w/ flags `-gsplit-dwarf -gpubnames`. This generated 2 DWO files. Then, the test incrementally adds breakpoints, and does a type lookup, and the count should increase for each of these as new DWO files get loaded to support these. ``` $ bin/lldb-dotest -p TestStats.py ~/llvm-sand/external/llvm-project/lldb/test/API/commands/statistics/basic/ -- Ran 20 tests in 211.738s OK (skipped=3) ``` >From 57483ee0f44f8bbed325268e7d1d40b1a0403aa1 Mon Sep 17 00:00:00 2001 From: Janet Yang Date: Mon, 16 Jun 2025 11:06:24 -0700 Subject: [PATCH] Add counter for number of DWO files loaded in statistics --- lldb/include/lldb/Symbol/SymbolFile.h | 5 +++ .../Python/lldbsuite/test/builders/builder.py | 25 ++- .../Python/lldbsuite/test/make/Makefile.rules | 4 +++ .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 1 + .../SymbolFile/DWARF/SymbolFileDWARF.h| 9 ++ .../SymbolFile/DWARF/SymbolFileDWARFDwo.cpp | 2 +- lldb/source/Target/Statistics.cpp | 5 +++ .../commands/statistics/basic/TestStats.py| 31 +++ .../API/commands/statistics/basic/baz.cpp | 12 +++ .../API/commands/statistics/basic/third.cpp | 7 + 10 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 lldb/test/API/commands/statistics/basic/baz.cpp create mode 100644 lldb/test/API/commands/statistics/basic/third.cpp diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 75c7f230ddf3d..42fbc2508889a 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -425,6 +425,11 @@ class SymbolFile : public PluginInterface { /// Reset the statistics for the symbol file. virtual void ResetStatistics() {} + /// Get the number of loaded DWO files for this symbol file. + /// This is used for statistics gathering and will return 0 for most + /// symbol file implementations except DWARF symbol files. + virtual uint32_t GetLoadedDwoFileCount() const { return 0; } + /// Get the additional modules that this symbol file uses to parse debug info. /// /// Some debug info is stored in stand alone object files that are represented diff --git a/lldb/packages/Python/lldbsuite/test/builders/builder.py b/lldb/packages/Python/lldbsuite/test/builders/builder.py index de05732469448..572abf590345c 100644 --- a/lldb/packages/Python/lldbsuite/test/builders/builder.py +++ b/lldb/packages/Python/lldbsuite/test/builders/builder.py @@ -247,13 +247,24 @@ def getLLDBObjRoot(self): def _getDebugInfoArgs(self, debug_info): if debug_info is None: return [] -if debug_info == "dwarf": -return ["MAKE_DSYM=NO"] -if debug_info == "dwo": -return ["MAKE_DSYM=NO", "MAKE_DWO=YES"] -if debug_info == "gmodules": -return ["MAKE_DSYM=NO", "MAKE_GMODULES=YES"] -return None + +debug_options = debug_info if isinstance(debug_info, list) else [debug_info] +option_flags = { +"dwarf": {"MAKE_DSYM": "NO"}, +"dwo": {"MAKE_DSYM": "NO", "MAKE_DWO": "YES"}, +"gmodules": {"MAKE_DSYM": "NO", "MAKE_GMODULES": "YES"}, +"debug_names": {"MAKE_DEBUG_NAMES": "YES"}, +} + +# Collect all flags, with later options overriding earlier ones
[Lldb-commits] [lldb] [lldb-dap][test] fix not supported error. (PR #144419)
https://github.com/da-viper created https://github.com/llvm/llvm-project/pull/144419 Fixes #144072 buildbot error. >From 22ea9d9c8afd879cacba769454ba115736df2c93 Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Mon, 16 Jun 2025 20:33:34 +0100 Subject: [PATCH] [lldb-dap][test] fix not supported error. --- .../tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py index 51ccf2ccbdcad..05adfb3e342b0 100644 --- a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py +++ b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py @@ -90,7 +90,13 @@ def test_supported_capability_x86_arch(self): len(breakpoint_ids), len(bp_lines), "expect correct number of breakpoints" ) self.continue_to_breakpoints(breakpoint_ids) -is_supported = self.dap_server.get_capability("supportsStepInTargetsRequest") + +try: +is_supported = self.dap_server.get_capability( +"supportsStepInTargetsRequest" +) +except dap_server.NotSupportedError: +is_supported = False self.assertEqual( is_supported, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add count for number of DWO files loaded in statistics (PR #144424)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: None (qxy11) Changes ## Summary A new `totalLoadedDwoFileCount` is added to available statisctics when calling "statistics dump". 1. The counter in SymbolFileDWARF `m_loaded_dwo_file_count` is added, and accessed through the `GetLoadedDwoFileCount()` 2. `m_loaded_dwo_file_count` is incremented through a new protected function `IncrementLoadedDwoFileCount()`, which is called in the constructor of `SymbolFileDWARFDwo` (as opposed to directly incrementing the counter in SymbolFileDwarf to prevent inconsistent updates to the counter in the future). 3. The `GetLoadedDwoFileCount()` API is added to `SymbolFile.h` for access to the DWO count from the symbol files loaded in `Statistics`, which returns 0 by default for all symbol file types except for `SymbolFileDWARF`. ## Testing **Manual Testing** On an internal script that has many DWO files, `statistics dump` was called before and after a `type lookup` command. The `totalLoadedDwoFileCount` increased as expected after the `type lookup`. ``` (lldb) statistics dump { ... "totalLoadedDwoFileCount": 29, } (lldb) type lookup folly::Optional::Storage typedef std::conditional ::StorageTriviallyDestructible, folly::Optional ::StorageNonTriviallyDestructible>::type typedef std::conditional ::StorageTriviallyDestructible, folly::Optional ::StorageNonTriviallyDestructible>::type ... (lldb) statistics dump { ... "totalLoadedDwoFileCount": 2160, } ``` **Unit test** Added a unit test that builds new "third.cpp" and "baz.cpp" files w/ flags `-gsplit-dwarf -gpubnames`. This generated 2 DWO files. Then, the test incrementally adds breakpoints, and does a type lookup, and the count should increase for each of these as new DWO files get loaded to support these. ``` $ bin/lldb-dotest -p TestStats.py ~/llvm-sand/external/llvm-project/lldb/test/API/commands/statistics/basic/ -- Ran 20 tests in 211.738s OK (skipped=3) ``` --- Full diff: https://github.com/llvm/llvm-project/pull/144424.diff 10 Files Affected: - (modified) lldb/include/lldb/Symbol/SymbolFile.h (+5) - (modified) lldb/packages/Python/lldbsuite/test/builders/builder.py (+18-7) - (modified) lldb/packages/Python/lldbsuite/test/make/Makefile.rules (+4) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (+1) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (+9) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp (+1-1) - (modified) lldb/source/Target/Statistics.cpp (+5) - (modified) lldb/test/API/commands/statistics/basic/TestStats.py (+31) - (added) lldb/test/API/commands/statistics/basic/baz.cpp (+12) - (added) lldb/test/API/commands/statistics/basic/third.cpp (+7) ``diff diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 75c7f230ddf3d..42fbc2508889a 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -425,6 +425,11 @@ class SymbolFile : public PluginInterface { /// Reset the statistics for the symbol file. virtual void ResetStatistics() {} + /// Get the number of loaded DWO files for this symbol file. + /// This is used for statistics gathering and will return 0 for most + /// symbol file implementations except DWARF symbol files. + virtual uint32_t GetLoadedDwoFileCount() const { return 0; } + /// Get the additional modules that this symbol file uses to parse debug info. /// /// Some debug info is stored in stand alone object files that are represented diff --git a/lldb/packages/Python/lldbsuite/test/builders/builder.py b/lldb/packages/Python/lldbsuite/test/builders/builder.py index de05732469448..572abf590345c 100644 --- a/lldb/packages/Python/lldbsuite/test/builders/builder.py +++ b/lldb/packages/Python/lldbsuite/test/builders/builder.py @@ -247,13 +247,24 @@ def getLLDBObjRoot(self): def _getDebugInfoArgs(self, debug_info): if debug_info is None: return [] -if debug_info == "dwarf": -return ["MAKE_DSYM=NO"] -if debug_info == "dwo": -return ["MAKE_DSYM=NO", "MAKE_DWO=YES"] -if debug_info == "gmodules": -return ["MAKE_DSYM=NO", "MAKE_GMODULES=YES"] -return None + +debug_options = debug_info if isinstance(debug_info, list) else [debug_info] +option_flags = { +"dwarf": {"MAKE_DSYM": "NO"}, +"dwo": {"MAKE_DSYM": "NO", "MAKE_DWO": "YES"}, +"gmodules": {"MAKE_DSYM": "NO", "MAKE_GMODULES": "YES"}, +"debug_names": {"MAKE_DEBUG_NAMES": "YES"}, +} + +# Collect all flags, with later options overriding earlier ones +flags = {} + +for option in debug_options: +
[Lldb-commits] [lldb] [lldb] Add count for number of DWO files loaded in statistics (PR #144424)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/144424 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Provide lr value in faulting frame on arm64 (PR #138805)
jasonmolenda wrote: > > I also needed to remove the brk #0xf000 instruction because lldb is not > > able to step over it -- it just ends up spinning forever. FWICS, it's not > > actually necessary now that you're stepping through the test. Nonetheless, > > this is a bug -- one that @DavidSpickett might be interested in :) > > Yes I've been asked a few times about it. GDB also has problems with it, but > probably does something slightly more useful. I'll speak to folks on that > side and see how we could handle this. @DavidSpickett sorry I missed this discussion a few weeks ago. Yeah, in debugserver aarch64 backend we check for the current instruction being `brk #0xf000` specifically and move $pc to the next instruction. Customers were using `__builtin_debugtrap()` in their code to force a break in the debugger, and wanted to continue stepping after hitting that, like they could on Intel systems (where the pc was past the interrupt instruction). I wasn't sure if it was best to special case this in debugserver, or up in lldb in some architecture dependent stepping plan when we're stopped at this instruction, I may have chosen poorly. https://github.com/llvm/llvm-project/pull/138805 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add supported languages in package.json (PR #144414)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: None (DrSergei) Changes This patch fixes the [problem](https://github.com/llvm/llvm-project/issues/144239). It was caused by missing supported languages list in `package.json`. VSCode uses `guessDebugger` [function](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts#L344) to find supported debuggers based on supported languages in case of opened file. It uses `interestedInLanguage` [function](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/debug/common/debugger.ts#L171) to do that, so we should provide list of supported languages. Also, fixed typo in `fortran`. Before:  After:  --- Full diff: https://github.com/llvm/llvm-project/pull/144414.diff 1 Files Affected: - (modified) lldb/tools/lldb-dap/package.json (+17-1) ``diff diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json index 0f51c4f935e33..b150dee792c34 100644 --- a/lldb/tools/lldb-dap/package.json +++ b/lldb/tools/lldb-dap/package.json @@ -290,7 +290,7 @@ "language": "d" }, { -"language": "fortan" +"language": "fortran" }, { "language": "fortran-modern" @@ -318,6 +318,22 @@ { "type": "lldb-dap", "label": "LLDB DAP Debugger", +"languages": [ + "ada", + "arm", + "c", + "cpp", + "crystal", + "d", + "fortran", + "fortran-modern", + "nim", + "objective-c", + "objectpascal", + "pascal", + "rust", + "swift" +], "configurationAttributes": { "launch": { "required": [ `` https://github.com/llvm/llvm-project/pull/144414 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [lldb] [llvm] [mlir] A couple of grammar fixes (PR #144368)
https://github.com/GameRoMan created https://github.com/llvm/llvm-project/pull/144368 None >From 2b50682f230efa03c3b9a1f5c5e48e708734bf4d Mon Sep 17 00:00:00 2001 From: Roman A <121314722+gamero...@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:59:01 +0100 Subject: [PATCH] A couple of grammar fixes --- clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp | 2 +- clang/test/AST/HLSL/RootSignatures-AST.hlsl | 2 +- clang/test/Modules/safe_buffers_optout.cpp | 4 ++-- lldb/include/lldb/Target/CoreFileMemoryRanges.h | 2 +- llvm/include/llvm/Analysis/VectorUtils.h | 2 +- llvm/lib/IR/DebugInfo.cpp| 2 +- llvm/lib/Transforms/Utils/IRNormalizer.cpp | 2 +- mlir/lib/Bindings/Python/IRAttributes.cpp| 2 +- mlir/test/Dialect/Vector/vector-reduce-to-contract.mlir | 2 +- mlir/tools/mlir-tblgen/EnumsGen.cpp | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp index 30fcba367db67..85dc9eb71ab7e 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp @@ -151,7 +151,7 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { StringRef ExtraReference = ""; if (MainTypeEndLoc.isValid() && TypeRange.fullyContains(MainTypeEndLoc)) { // Each type introduced in a typedef can specify being a reference or - // pointer type seperately, so we need to sigure out if the new using-decl + // pointer type separately, so we need to sigure out if the new using-decl // needs to be to a reference or pointer as well. const SourceLocation Tok = utils::lexer::findPreviousAnyTokenKind( MatchedDecl->getLocation(), SM, LO, tok::TokenKind::star, diff --git a/clang/test/AST/HLSL/RootSignatures-AST.hlsl b/clang/test/AST/HLSL/RootSignatures-AST.hlsl index c700174da764d..1a0f17757796c 100644 --- a/clang/test/AST/HLSL/RootSignatures-AST.hlsl +++ b/clang/test/AST/HLSL/RootSignatures-AST.hlsl @@ -61,7 +61,7 @@ void same_rs_string_main() {} "DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))" // Ensure that when we define a different type root signature that it creates -// a seperate decl and identifier to reference +// a separate decl and identifier to reference // CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[DIFF_RS_DECL:__hlsl_rootsig_decl_\d*]] // CHECK-SAME: RootElements{ diff --git a/clang/test/Modules/safe_buffers_optout.cpp b/clang/test/Modules/safe_buffers_optout.cpp index 8c3d6a235d399..39020a48925e1 100644 --- a/clang/test/Modules/safe_buffers_optout.cpp +++ b/clang/test/Modules/safe_buffers_optout.cpp @@ -96,7 +96,7 @@ int textual(int *p) { // `safe_buffers_test_base`. (So the module dependencies form a DAG.) // No expected warnings from base.h, test_sub1, or test_sub2 because they are -// in seperate modules, and the explicit commands that builds them have no +// in separate modules, and the explicit commands that builds them have no // `-Wunsafe-buffer-usage`. int foo(int * p) { @@ -122,7 +122,7 @@ int foo(int * p) { // `safe_buffers_test_base`. (So the module dependencies form a DAG.) // No expected warnings from base.h, test_sub1, or test_sub2 because they are -// in seperate modules, and the explicit commands that builds them have no +// in separate modules, and the explicit commands that builds them have no // `-Wunsafe-buffer-usage`. int foo(int * p) { diff --git a/lldb/include/lldb/Target/CoreFileMemoryRanges.h b/lldb/include/lldb/Target/CoreFileMemoryRanges.h index 78d01acca324e..ef56a02ddee27 100644 --- a/lldb/include/lldb/Target/CoreFileMemoryRanges.h +++ b/lldb/include/lldb/Target/CoreFileMemoryRanges.h @@ -50,7 +50,7 @@ class CoreFileMemoryRanges CoreFileMemoryRange> { public: /// Finalize and merge all overlapping ranges in this collection. Ranges - /// will be seperated based on permissions. + /// will be separated based on permissions. Status FinalizeCoreFileSaveRanges(); }; } // namespace lldb_private diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h index 53ba1e8f77791..4ef2ace34856a 100644 --- a/llvm/include/llvm/Analysis/VectorUtils.h +++ b/llvm/include/llvm/Analysis/VectorUtils.h @@ -144,7 +144,7 @@ LLVM_ABI bool isTriviallyVectorizable(Intrinsic::ID ID); /// Note: There are intrinsics where implementing vectorization for the /// intrinsic is redundant, but we want to implement scalarization of the /// vector. To prevent the requirement that an intrinsic also implements -/// vectorization we provide this seperate function. +/// vectorization we provide this separate function. LLVM_ABI bool isTriviallyScalarizable(Intrinsic::ID ID,
[Lldb-commits] [clang] [clang-tools-extra] [lldb] [llvm] [mlir] A couple of grammar fixes (PR #144368)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/144368 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -189,262 +298,322 @@ def _read_packet_thread(self): while not done: packet = read_packet(self.recv, trace_file=self.trace_file) # `packet` will be `None` on EOF. We want to pass it down to -# handle_recv_packet anyway so the main thread can handle unexpected -# termination of lldb-dap and stop waiting for new packets. +# handle_recv_packet anyway so the main thread can handle +# unexpected termination of lldb-dap and stop waiting for new +# packets. done = not self._handle_recv_packet(packet) finally: dump_dap_log(self.log_file) -def get_modules(self): -module_list = self.request_modules()["body"]["modules"] -modules = {} -for module in module_list: -modules[module["name"]] = module -return modules +def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: +"""Handles an incoming packet. -def get_output(self, category, timeout=0.0, clear=True): -self.output_condition.acquire() -output = None -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -elif timeout != 0.0: -self.output_condition.wait(timeout) -if category in self.output: -output = self.output[category] -if clear: -del self.output[category] -self.output_condition.release() -return output +Called by the read thread that is waiting for all incoming packets +to store the incoming packet in "self._recv_packets" in a thread safe +way. This function will then signal the "self._recv_condition" to +indicate a new packet is available. -def collect_output(self, category, timeout_secs, pattern, clear=True): -end_time = time.time() + timeout_secs -collected_output = "" -while end_time > time.time(): -output = self.get_output(category, timeout=0.25, clear=clear) -if output: -collected_output += output -if pattern is not None and pattern in output: -break -return collected_output if collected_output else None - -def _enqueue_recv_packet(self, packet: Optional[ProtocolMessage]): -self.recv_condition.acquire() -self.recv_packets.append(packet) -self.recv_condition.notify() -self.recv_condition.release() +Args: +packet: A new packet to store. -def _handle_recv_packet(self, packet: Optional[ProtocolMessage]) -> bool: -"""Called by the read thread that is waiting for all incoming packets -to store the incoming packet in "self.recv_packets" in a thread safe -way. This function will then signal the "self.recv_condition" to -indicate a new packet is available. Returns True if the caller -should keep calling this function for more packets. +Returns: +True if the caller should keep calling this function for more +packets. """ -# If EOF, notify the read thread by enqueuing a None. -if not packet: -self._enqueue_recv_packet(None) -return False - -# Check the packet to see if is an event packet -keepGoing = True -packet_type = packet["type"] -if packet_type == "event": -event = packet["event"] -body = None -if "body" in packet: -body = packet["body"] -# Handle the event packet and cache information from these packets -# as they come in -if event == "output": -# Store any output we receive so clients can retrieve it later. -category = body["category"] -output = body["output"] -self.output_condition.acquire() -if category in self.output: -self.output[category] += output -else: -self.output[category] = output -self.output_condition.notify() -self.output_condition.release() -# no need to add 'output' event packets to our packets list -return keepGoing -elif event == "initialized": -self.initialized = True -elif event == "process": -# When a new process is attached or launched, remember the -# details that are available in the body of the event -self.process_event_body = body -elif event == "exited": -# Process exited, mark the status to indicate the process is not -# alive. -self.exit_status = body["exitCode"] -
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -10,17 +10,117 @@ import subprocess import signal import sys +from dataclasses import dataclass import threading import time -from typing import Any, Optional, Union, BinaryIO, TextIO +from typing import ( +IO, +Any, +Callable, +Dict, +List, +Optional, +Tuple, +TypeGuard, +TypeVar, +TypedDict, +Union, +BinaryIO, +TextIO, +Literal, +cast, +) ## DAP type references -Event = dict[str, Any] -Request = dict[str, Any] -Response = dict[str, Any] + +T = TypeVar("T") + + +class Event(TypedDict): +type: Literal["event"] +seq: Literal[0] +event: str +body: Optional[dict] + + +class Request(TypedDict): +type: Literal["request"] +seq: int +command: str +arguments: Optional[dict] + + +class Response(TypedDict): +type: Literal["response"] +seq: Literal[0] +request_seq: int +success: bool +command: str +message: Optional[str] +body: Optional[dict] + + ProtocolMessage = Union[Event, Request, Response] +class AttachOrLaunchArguments(TypedDict, total=False): +stopOnEntry: bool +disableASLR: bool +disableSTDIO: bool +enableAutoVariableSummaries: bool +displayExtendedBacktrace: bool +enableSyntheticChildDebugging: bool +initCommands: List[str] +preRunCommands: List[str] +postRunCommands: List[str] +stopCommands: List[str] +exitCommands: List[str] +terminateCommands: List[str] +sourceMap: Union[List[Tuple[str, str]], Dict[str, str]] +sourcePath: str +debuggerRoot: str +commandEscapePrefix: str +customFrameFormat: str +customThreadFormat: str + + +class LaunchArguments(AttachOrLaunchArguments, total=False): +program: str +args: List[str] +cwd: str +env: Dict[str, str] +shellExpandArguments: bool +runInTerminal: bool +launchCommands: List[str] + + +class AttachArguments(AttachOrLaunchArguments, total=False): +program: str +pid: int +waitFor: bool +attachCommands: List[str] +coreFile: str +gdbRemotePort: int +gdbRemoteHostname: str + + +class BreakpiontData(TypedDict, total=False): +column: int +condition: str +hitCondition: str +logMessage: str +mode: str + + +class SourceBreakpoint(BreakpiontData): da-viper wrote: ```suggestion class SourceBreakpoint(BreakpointData): ``` https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
@@ -152,35 +246,50 @@ def __init__( self.log_file = log_file self.send = send self.recv = recv -self.recv_packets: list[Optional[ProtocolMessage]] = [] -self.recv_condition = threading.Condition() -self.recv_thread = threading.Thread(target=self._read_packet_thread) -self.process_event_body = None -self.exit_status: Optional[int] = None -self.capabilities: dict[str, Any] = {} -self.progress_events: list[Event] = [] -self.reverse_requests = [] -self.sequence = 1 -self.threads = None -self.thread_stop_reasons = {} -self.recv_thread.start() -self.output_condition = threading.Condition() -self.output: dict[str, list[str]] = {} -self.configuration_done_sent = False -self.initialized = False -self.frame_scopes = {} +# Packets that have been received and processed but have not yet been +# requested by a test case. +self._pending_packets: List[Optional[ProtocolMessage]] = [] +# Recieved packets that have not yet been processed. +self._recv_packets: List[Optional[ProtocolMessage]] = [] +# Used as a mutex for _recv_packets and for notify when _recv_packets +# changes. +self._recv_condition = threading.Condition() +self._recv_thread = threading.Thread(target=self._read_packet_thread) + +# session state self.init_commands = init_commands -self.resolved_breakpoints = {} +self.exit_status: Optional[int] = None +self.capabilities: Optional[Dict] = None +self.initialized: bool = False +self.configuration_done_sent: bool = False +self.process_event_body: Optional[Dict] = None +self.terminated: bool = False +self.events: List[Event] = [] +self.progress_events: List[Event] = [] +self.reverse_requests: List[Request] = [] +self.module_events: List[Dict] = [] +self.sequence: int = 1 +self.output: Dict[str, str] = {} + +# debuggee state +self.threads: Optional[dict] = None +self.thread_stop_reasons: Dict[str, Any] = {} +self.frame_scopes: Dict[str, Any] = {} +# keyed by breakpoint id +self.resolved_breakpoints: Dict[int, bool] = {} da-viper wrote: ```suggestion self.resolved_breakpoints: Dict[str, bool] = {} ``` https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
https://github.com/da-viper edited https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring DebugCommunication to improve test consistency. (PR #143818)
https://github.com/da-viper commented: LGTM mostly just nits. https://github.com/llvm/llvm-project/pull/143818 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [lldb] [Clang][PowerPC] Add __dmr type and DMF integer calculation builtins (PR #142480)
https://github.com/maryammo updated https://github.com/llvm/llvm-project/pull/142480 >From 5ef7a4ca7c2a838a6b2100968d5023e0797b2848 Mon Sep 17 00:00:00 2001 From: Maryam Moghadas Date: Mon, 2 Jun 2025 19:54:57 + Subject: [PATCH 1/3] [Clang][PowerPC] Add __dmr type and DMF integer calculation builtins Define the __dmr type used to manipulate the new DMR registers introduced by the Dense Math Facility (DMF) on PowerPC, and add six Clang builtins that correspond to the integer outer-product accumulate to ACC instructions: __builtin_mma_dmxvi8gerx4, __builtin_mma_pmdmxvi8gerx4, __builtin_mma_dmxvi8gerx4pp, __builtin_mma_pmdmxvi8gerx4pp, __builtin_mma_dmxvi8gerx4spp, and __builtin_mma_pmdmxvi8gerx4spp. --- clang/include/clang/Basic/BuiltinsPPC.def | 12 ++ clang/include/clang/Basic/PPCTypes.def| 1 + clang/lib/AST/ASTContext.cpp | 1 + clang/test/AST/ast-dump-ppc-types.c | 13 +- .../CodeGen/PowerPC/builtins-ppc-mmaplus.c| 94 + .../PowerPC/ppc-future-mma-builtin-err.c | 21 ++ ...ppc-future-paired-vec-memops-builtin-err.c | 20 ++ .../test/CodeGen/PowerPC/ppc-mmaplus-types.c | 184 ++ .../test/CodeGenCXX/ppc-mangle-mma-types.cpp | 5 + clang/test/Sema/ppc-pair-mma-types.c | 98 ++ .../TypeSystem/Clang/TypeSystemClang.cpp | 1 + 11 files changed, 447 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGen/PowerPC/builtins-ppc-mmaplus.c create mode 100644 clang/test/CodeGen/PowerPC/ppc-future-mma-builtin-err.c create mode 100644 clang/test/CodeGen/PowerPC/ppc-future-paired-vec-memops-builtin-err.c create mode 100644 clang/test/CodeGen/PowerPC/ppc-mmaplus-types.c diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index bb7d54bbb793e..099500754a0e0 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -1134,6 +1134,18 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2np, "vW512*VVi15i15i3", true, "mma,paired-vector-memops") UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true, "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_dmxvi8gerx4, "vW1024*W256V", false, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_pmdmxvi8gerx4, "vW1024*W256Vi255i15i15", false, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_dmxvi8gerx4pp, "vW1024*W256V", true, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_pmdmxvi8gerx4pp, "vW1024*W256Vi255i15i15", true, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_dmxvi8gerx4spp, "vW1024*W256V", true, + "mma,paired-vector-memops") +UNALIASED_CUSTOM_BUILTIN(mma_pmdmxvi8gerx4spp, "vW1024*W256Vi255i15i15", true, + "mma,paired-vector-memops") // FIXME: Obviously incomplete. diff --git a/clang/include/clang/Basic/PPCTypes.def b/clang/include/clang/Basic/PPCTypes.def index 9e2cb2aedc9fc..cfc9de3a473d4 100644 --- a/clang/include/clang/Basic/PPCTypes.def +++ b/clang/include/clang/Basic/PPCTypes.def @@ -30,6 +30,7 @@ #endif +PPC_VECTOR_MMA_TYPE(__dmr, VectorDmr, 1024) PPC_VECTOR_MMA_TYPE(__vector_quad, VectorQuad, 512) PPC_VECTOR_VSX_TYPE(__vector_pair, VectorPair, 256) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 45f9602856840..ffb4ca61b00c4 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3455,6 +3455,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, case BuiltinType::BFloat16: case BuiltinType::VectorQuad: case BuiltinType::VectorPair: +case BuiltinType::VectorDmr: OS << "?"; return; diff --git a/clang/test/AST/ast-dump-ppc-types.c b/clang/test/AST/ast-dump-ppc-types.c index 26ae5441f20d7..a430268284413 100644 --- a/clang/test/AST/ast-dump-ppc-types.c +++ b/clang/test/AST/ast-dump-ppc-types.c @@ -1,9 +1,11 @@ +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu future \ +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr10 \ -// RUN: -ast-dump -ast-dump-filter __vector %s | FileCheck %s +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr9 \ -// RUN: -ast-dump -ast-dump-filter __vector %s | FileCheck %s +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr8 \ -// RUN: -ast-dump -ast-dump-filter __vector %s | FileCheck %s +// RUN: -ast-dump %s | FileCheck %s // RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck %s \ // RUN: --check-prefix=CHECK-X86_64 // RUN: %clang_cc1 -triple arm-unknown-unknown -ast-dump %s | FileCheck %s \ @@ -15,16 +17,21 @@
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/143628 >From 42e664808a7bde374e5a1f2132d52636499bf4e6 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 12 Jun 2025 16:33:55 -0700 Subject: [PATCH] [lldb] Add MCP support to LLDB https://discourse.llvm.org/t/rfc-adding-mcp-support-to-lldb/86798 --- lldb/cmake/modules/LLDBConfig.cmake | 1 + lldb/include/lldb/Core/Debugger.h | 6 + lldb/include/lldb/Core/PluginManager.h| 11 + lldb/include/lldb/Core/ProtocolServer.h | 39 +++ .../Interpreter/CommandOptionArgumentTable.h | 1 + lldb/include/lldb/lldb-enumerations.h | 1 + lldb/include/lldb/lldb-forward.h | 3 +- lldb/include/lldb/lldb-private-interfaces.h | 2 + lldb/source/Commands/CMakeLists.txt | 1 + .../Commands/CommandObjectProtocolServer.cpp | 186 +++ .../Commands/CommandObjectProtocolServer.h| 25 ++ lldb/source/Core/CMakeLists.txt | 1 + lldb/source/Core/Debugger.cpp | 24 ++ lldb/source/Core/PluginManager.cpp| 32 ++ lldb/source/Core/ProtocolServer.cpp | 21 ++ .../source/Interpreter/CommandInterpreter.cpp | 2 + lldb/source/Plugins/CMakeLists.txt| 4 + lldb/source/Plugins/Protocol/CMakeLists.txt | 1 + .../Plugins/Protocol/MCP/CMakeLists.txt | 13 + lldb/source/Plugins/Protocol/MCP/MCPError.cpp | 34 ++ lldb/source/Plugins/Protocol/MCP/MCPError.h | 33 ++ lldb/source/Plugins/Protocol/MCP/Protocol.cpp | 203 lldb/source/Plugins/Protocol/MCP/Protocol.h | 127 .../Protocol/MCP/ProtocolServerMCP.cpp| 306 ++ .../Plugins/Protocol/MCP/ProtocolServerMCP.h | 94 ++ lldb/source/Plugins/Protocol/MCP/Tool.cpp | 70 lldb/source/Plugins/Protocol/MCP/Tool.h | 55 lldb/unittests/CMakeLists.txt | 4 + lldb/unittests/DAP/ProtocolTypesTest.cpp | 34 +- lldb/unittests/Protocol/CMakeLists.txt| 12 + .../Protocol/ProtocolMCPServerTest.cpp| 195 +++ lldb/unittests/Protocol/ProtocolMCPTest.cpp | 135 lldb/unittests/TestingSupport/TestUtilities.h | 9 + 33 files changed, 1664 insertions(+), 21 deletions(-) create mode 100644 lldb/include/lldb/Core/ProtocolServer.h create mode 100644 lldb/source/Commands/CommandObjectProtocolServer.cpp create mode 100644 lldb/source/Commands/CommandObjectProtocolServer.h create mode 100644 lldb/source/Core/ProtocolServer.cpp create mode 100644 lldb/source/Plugins/Protocol/CMakeLists.txt create mode 100644 lldb/source/Plugins/Protocol/MCP/CMakeLists.txt create mode 100644 lldb/source/Plugins/Protocol/MCP/MCPError.cpp create mode 100644 lldb/source/Plugins/Protocol/MCP/MCPError.h create mode 100644 lldb/source/Plugins/Protocol/MCP/Protocol.cpp create mode 100644 lldb/source/Plugins/Protocol/MCP/Protocol.h create mode 100644 lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp create mode 100644 lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.h create mode 100644 lldb/source/Plugins/Protocol/MCP/Tool.cpp create mode 100644 lldb/source/Plugins/Protocol/MCP/Tool.h create mode 100644 lldb/unittests/Protocol/CMakeLists.txt create mode 100644 lldb/unittests/Protocol/ProtocolMCPServerTest.cpp create mode 100644 lldb/unittests/Protocol/ProtocolMCPTest.cpp diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 37b823feb584b..8c30b6e09d2c7 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -67,6 +67,7 @@ add_optional_dependency(LLDB_ENABLE_FBSDVMCORE "Enable libfbsdvmcore support in option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON) option(LLDB_BUILD_FRAMEWORK "Build LLDB.framework (Darwin only)" OFF) +option(LLDB_ENABLE_PROTOCOL_SERVERS "Enable protocol servers (e.g. MCP) in LLDB" ON) option(LLDB_NO_INSTALL_DEFAULT_RPATH "Disable default RPATH settings in binaries" OFF) option(LLDB_USE_SYSTEM_DEBUGSERVER "Use the system's debugserver for testing (Darwin only)." OFF) option(LLDB_SKIP_STRIP "Whether to skip stripping of binaries when installing lldb." OFF) diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index d73aba1e3ce58..0f6659d1a0bf7 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -598,6 +598,10 @@ class Debugger : public std::enable_shared_from_this, void FlushProcessOutput(Process &process, bool flush_stdout, bool flush_stderr); + void AddProtocolServer(lldb::ProtocolServerSP protocol_server_sp); + void RemoveProtocolServer(lldb::ProtocolServerSP protocol_server_sp); + lldb::ProtocolServerSP GetProtocolServer(llvm::StringRef protocol) const; + SourceManager::SourceFileCache &GetSourceFileCache() { return m_source_file_cache; } @@ -768,6 +772,8 @@ class Debugg
[Lldb-commits] [lldb] 539cf82 - [lldb-dap] Use structured types for stepInTargets request (#144072)
Author: Ebuka Ezike Date: 2025-06-16T19:24:59+01:00 New Revision: 539cf824259cbb23ccc68b83ef3cde575ca50842 URL: https://github.com/llvm/llvm-project/commit/539cf824259cbb23ccc68b83ef3cde575ca50842 DIFF: https://github.com/llvm/llvm-project/commit/539cf824259cbb23ccc68b83ef3cde575ca50842.diff LOG: [lldb-dap] Use structured types for stepInTargets request (#144072) uses the `SendTargetCapabilities` from #142831 Added: Modified: lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py lldb/tools/lldb-dap/EventHelper.cpp lldb/tools/lldb-dap/Handler/RequestHandler.h lldb/tools/lldb-dap/Handler/StepInTargetsRequestHandler.cpp lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp lldb/tools/lldb-dap/Protocol/ProtocolRequests.h lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp lldb/tools/lldb-dap/Protocol/ProtocolTypes.h lldb/unittests/DAP/ProtocolTypesTest.cpp Removed: 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 9786678aa53f9..baf2d4ae542ba 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 @@ -494,7 +494,7 @@ def wait_for_terminated(self, timeout: Optional[float] = None): raise ValueError("didn't get terminated event") return event_dict -def get_capability(self, key): +def get_capability(self, key: str): """Get a value for the given key if it there is a key/value pair in the capabilities reported by the adapter. """ diff --git a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py index 07acfe07c9ffc..51ccf2ccbdcad 100644 --- a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py +++ b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py @@ -78,3 +78,47 @@ def test_basic(self): leaf_frame = self.dap_server.get_stackFrame() self.assertIsNotNone(leaf_frame, "expect a leaf frame") self.assertEqual(step_in_targets[1]["label"], leaf_frame["name"]) + +@skipIf(archs=no_match(["x86", "x86_64"])) +def test_supported_capability_x86_arch(self): +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.cpp" +bp_lines = [line_number(source, "// set breakpoint here")] +breakpoint_ids = self.set_source_breakpoints(source, bp_lines) +self.assertEqual( +len(breakpoint_ids), len(bp_lines), "expect correct number of breakpoints" +) +self.continue_to_breakpoints(breakpoint_ids) +is_supported = self.dap_server.get_capability("supportsStepInTargetsRequest") + +self.assertEqual( +is_supported, +True, +f"expect capability `stepInTarget` is supported with architecture {self.getArchitecture()}", +) +# clear breakpoints. +self.set_source_breakpoints(source, []) +self.continue_to_exit() + +@skipIf(archs=["x86", "x86_64"]) +def test_supported_capability_other_archs(self): +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.cpp" +bp_lines = [line_number(source, "// set breakpoint here")] +breakpoint_ids = self.set_source_breakpoints(source, bp_lines) +self.assertEqual( +len(breakpoint_ids), len(bp_lines), "expect correct number of breakpoints" +) +self.continue_to_breakpoints(breakpoint_ids) +is_supported = self.dap_server.get_capability("supportsStepInTargetsRequest") + +self.assertEqual( +is_supported, +False, +f"expect capability `stepInTarget` is not supported with architecture {self.getArchitecture()}", +) +# clear breakpoints. +self.set_source_breakpoints(source, []) +self.continue_to_exit() diff --git a/lldb/tools/lldb-dap/EventHelper.cpp b/lldb/tools/lldb-dap/EventHelper.cpp index 9641f29698b10..364cc7ab4ef8c 100644 --- a/lldb/tools/lldb-dap/EventHelper.cpp +++ b/lldb/tools/lldb-dap/EventHelper.cpp @@ -44,6 +44,11 @@ void SendTargetBasedCapabilities(DAP &dap) { protocol::CapabilitiesEventBody body; + const llvm::StringRef target_triple = dap.target.GetTriple(); + if (target_triple.starts_with("x86")) +body.capabilities.supportedFeatures.insert( +protocol::eAdapterFeatureStepInTargetsRequest); + // We only support restarting launch requests not attach requests. if (dap.last_launch_request) body.capabilities.supportedFeatures.insert( diff --git a/lldb/tools/lldb-dap/Handler/Reques
[Lldb-commits] [lldb] [lldb-dap] Use structured types for stepInTargets request (PR #144072)
https://github.com/da-viper closed https://github.com/llvm/llvm-project/pull/144072 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
JDevlieghere wrote: - Added a CMake flag to disable building protocol servers at configuration time. - Added a link to the spec, settled on 2024-11-05 as that's what Claude Desktop supports right now and we weren't using anything from 2025-03-26. - Eliminated all threads except the one that runs the MCP MainLoop, which now serves all the clients. - Correctly handle notifications instead of treating them like requests. https://github.com/llvm/llvm-project/pull/143628 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
@@ -0,0 +1,280 @@ +//===- ProtocolServerMCP.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ProtocolServerMCP.h" +#include "MCPError.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/Threading.h" +#include + +using namespace lldb_private; +using namespace lldb_private::mcp; +using namespace llvm; + +LLDB_PLUGIN_DEFINE(ProtocolServerMCP) + +ProtocolServerMCP::ProtocolServerMCP(Debugger &debugger) +: ProtocolServer(), m_debugger(debugger) { + AddHandler("initialize", std::bind(&ProtocolServerMCP::InitializeHandler, + this, std::placeholders::_1)); + AddHandler("tools/list", std::bind(&ProtocolServerMCP::ToolsListHandler, this, + std::placeholders::_1)); + AddHandler("tools/call", std::bind(&ProtocolServerMCP::ToolsCallHandler, this, + std::placeholders::_1)); + AddTool(std::make_unique( + "lldb_command", "Run an lldb command.", m_debugger)); +} + +ProtocolServerMCP::~ProtocolServerMCP() { llvm::consumeError(Stop()); } + +void ProtocolServerMCP::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), +GetPluginDescriptionStatic(), CreateInstance); +} + +void ProtocolServerMCP::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb::ProtocolServerSP ProtocolServerMCP::CreateInstance(Debugger &debugger) { + return std::make_shared(debugger); +} + +llvm::StringRef ProtocolServerMCP::GetPluginDescriptionStatic() { + return "MCP Server."; +} + +llvm::Expected +ProtocolServerMCP::Handle(protocol::Request request) { + auto it = m_handlers.find(request.method); + if (it != m_handlers.end()) +return it->second(request); + + return make_error( + llvm::formatv("no handler for request: {0}", request.method).str(), 1); +} + +llvm::Error ProtocolServerMCP::Start(ProtocolServer::Connection connection) { + std::lock_guard guard(m_server_mutex); + + if (m_running) +return llvm::createStringError("server already running"); + + Status status; + m_listener = Socket::Create(connection.protocol, status); + if (status.Fail()) +return status.takeError(); + + status = m_listener->Listen(connection.name, /*backlog=*/5); + if (status.Fail()) +return status.takeError(); + + std::string address = + llvm::join(m_listener->GetListeningConnectionURI(), ", "); + Log *log = GetLog(LLDBLog::Host); + LLDB_LOG(log, "MCP server started with connection listeners: {0}", address); + + auto handles = m_listener->Accept(m_loop, [=](std::unique_ptr sock) { +std::lock_guard guard(m_server_mutex); + +const std::string client_name = +llvm::formatv("client-{0}", m_clients.size() + 1).str(); +LLDB_LOG(log, "client {0} connected", client_name); + +lldb::IOObjectSP io(std::move(sock)); + +m_clients.emplace_back(io, [=]() { + llvm::set_thread_name(client_name + "-runloop"); + if (auto Err = Run(std::make_unique(io, io))) +LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(Err), "MCP Error: {0}"); +}); + }); + if (llvm::Error error = handles.takeError()) +return error; + + m_read_handles = std::move(*handles); + m_loop_thread = std::thread([=] { +llvm::set_thread_name("mcp-runloop"); +m_loop.Run(); + }); + + return llvm::Error::success(); +} + +llvm::Error ProtocolServerMCP::Stop() { + { +std::lock_guard guard(m_server_mutex); +m_running = false; + } + + // Stop accepting new connections. + m_loop.AddPendingCallback( + [](MainLoopBase &loop) { loop.RequestTermination(); }); + + // Wait for the main loop to exit. + if (m_loop_thread.joinable()) +m_loop_thread.join(); + + // Wait for all our clients to exit. + for (auto &client : m_clients) { +client.first->Close(); JDevlieghere wrote: Thanks Pavel, I knew about all those things in isolation but I didn't put the pieces together. There's no reason we can't do this fully in the MainLoop. https://github.com/llvm/llvm-project/pull/143628 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Fix source references (PR #144364)
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/144364 >From 80f7d8b3ffd48a94414374518c022ba682fb7be1 Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Mon, 16 Jun 2025 11:00:05 +0100 Subject: [PATCH 1/2] [lldb-dap] Fix source references The protocol expects that `sourceReference` be less than `(2^31)-1`, but we currently represent memory address as source reference, this can be truncated either when sending through json or by the client. Instead, generate new source references based on the memory address. Make the `CreateSource` function return an optional source. --- .../TestDAP_breakpointAssembly.py | 14 ++--- lldb/tools/lldb-dap/Breakpoint.cpp| 7 ++- lldb/tools/lldb-dap/DAP.cpp | 19 +++ lldb/tools/lldb-dap/DAP.h | 7 ++- .../Handler/DisassembleRequestHandler.cpp | 16 +++--- .../Handler/LocationsRequestHandler.cpp | 22 +++- .../lldb-dap/Handler/SourceRequestHandler.cpp | 32 +++- .../Handler/StackTraceRequestHandler.cpp | 2 +- lldb/tools/lldb-dap/JSONUtils.cpp | 12 +++-- lldb/tools/lldb-dap/JSONUtils.h | 5 +- .../lldb-dap/Protocol/ProtocolRequests.h | 2 +- .../tools/lldb-dap/Protocol/ProtocolTypes.cpp | 2 +- lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 3 +- lldb/tools/lldb-dap/ProtocolUtils.cpp | 51 --- lldb/tools/lldb-dap/ProtocolUtils.h | 13 +++-- lldb/tools/lldb-dap/SourceBreakpoint.cpp | 8 ++- 16 files changed, 152 insertions(+), 63 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py index 8bccc2bcf4156..674bfe4199b4a 100644 --- a/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py +++ b/lldb/test/API/tools/lldb-dap/breakpoint-assembly/TestDAP_breakpointAssembly.py @@ -67,19 +67,19 @@ def test_break_on_invalid_source_reference(self): "Invalid sourceReference.", ) -# Verify that setting a breakpoint on a source reference without a symbol also fails +# Verify that setting a breakpoint on a source reference that is not created fails response = self.dap_server.request_setBreakpoints( -Source(source_reference=0), [1] +Source(source_reference=200), [1] ) self.assertIsNotNone(response) breakpoints = response["body"]["breakpoints"] self.assertEqual(len(breakpoints), 1) -breakpoint = breakpoints[0] +break_point = breakpoints[0] self.assertFalse( -breakpoint["verified"], "Expected breakpoint to not be verified" +break_point["verified"], "Expected breakpoint to not be verified" ) -self.assertIn("message", breakpoint, "Expected message to be present") +self.assertIn("message", break_point, "Expected message to be present") self.assertEqual( -breakpoint["message"], -"Breakpoints in assembly without a valid symbol are not supported yet.", +break_point["message"], +"Invalid sourceReference.", ) diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp b/lldb/tools/lldb-dap/Breakpoint.cpp index ef5646c4c3d16..e1b073405ebb2 100644 --- a/lldb/tools/lldb-dap/Breakpoint.cpp +++ b/lldb/tools/lldb-dap/Breakpoint.cpp @@ -64,8 +64,11 @@ protocol::Breakpoint Breakpoint::ToProtocolBreakpoint() { "0x" + llvm::utohexstr(bp_addr.GetLoadAddress(m_bp.GetTarget())); breakpoint.instructionReference = formatted_addr; -auto source = CreateSource(bp_addr, m_dap.target); -if (!IsAssemblySource(source)) { +std::optional source = +CreateSource(bp_addr, m_dap.target, [this](lldb::addr_t addr) { + return m_dap.CreateSourceReference(addr); +}); +if (source && !IsAssemblySource(*source)) { auto line_entry = bp_addr.GetLineEntry(); const auto line = line_entry.GetLine(); if (line != LLDB_INVALID_LINE_NUMBER) diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index 9fe8227cd2d6f..56bb5903080dc 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -510,6 +510,25 @@ DAP::SendFormattedOutput(OutputType o, const char *format, ...) { o, llvm::StringRef(buffer, std::min(actual_length, sizeof(buffer; } +int32_t DAP::CreateSourceReference(lldb::addr_t address) { + auto iter = llvm::find(source_references, address); + if (iter != source_references.end()) +return std::distance(source_references.begin(), iter) + 1; + + source_references.emplace_back(address); + return static_cast(source_references.size()); +} + +std::optional DAP::GetSourceReferenceAddress(int32_t reference) { + if (reference <= LLDB_DAP_INVALID_SRC_REF) +return std::nullopt; + + if (static_cast(reference) > sourc
[Lldb-commits] [lldb] [lldb-dap] Fix source references (PR #144364)
@@ -510,6 +510,25 @@ DAP::SendFormattedOutput(OutputType o, const char *format, ...) { o, llvm::StringRef(buffer, std::min(actual_length, sizeof(buffer; } +int32_t DAP::CreateSourceReference(lldb::addr_t address) { + auto iter = llvm::find(source_references, address); da-viper wrote: changed to std::lower_bound https://github.com/llvm/llvm-project/pull/144364 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
@@ -0,0 +1,72 @@ +//===- Tool.cpp ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Tool.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandReturnObject.h" + +using namespace lldb_private::mcp; +using namespace llvm; + +Tool::Tool(std::string name, std::string description) +: m_name(std::move(name)), m_description(std::move(description)) {} + +protocol::ToolDefinition Tool::GetDefinition() const { + protocol::ToolDefinition definition; + definition.name = m_name; + definition.description.emplace(m_description); + + if (std::optional input_schema = GetSchema()) +definition.inputSchema = *input_schema; + + if (m_annotations) +definition.annotations = m_annotations; + + return definition; +} + +LLDBCommandTool::LLDBCommandTool(std::string name, std::string description, + Debugger &debugger) +: Tool(std::move(name), std::move(description)), m_debugger(debugger) {} + +protocol::TextResult LLDBCommandTool::Call(const llvm::json::Value &args) { + std::string arguments; + if (const json::Object *args_obj = args.getAsObject()) { +if (const json::Value *s = args_obj->get("arguments")) { + arguments = s->getAsString().value_or(""); +} + } + + CommandReturnObject result(/*colors=*/false); + m_debugger.GetCommandInterpreter().HandleCommand(arguments.c_str(), JDevlieghere wrote: I've added a FIXME for now. https://github.com/llvm/llvm-project/pull/143628 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/143628 >From 4d6de9076531ce66e0dc7aabaaba765a63c03e42 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 12 Jun 2025 16:33:55 -0700 Subject: [PATCH] [lldb] Add MCP support to LLDB https://discourse.llvm.org/t/rfc-adding-mcp-support-to-lldb/86798 --- lldb/cmake/modules/LLDBConfig.cmake | 1 + lldb/include/lldb/Core/Debugger.h | 6 + lldb/include/lldb/Core/PluginManager.h| 11 + lldb/include/lldb/Core/ProtocolServer.h | 39 +++ .../Interpreter/CommandOptionArgumentTable.h | 1 + lldb/include/lldb/lldb-enumerations.h | 1 + lldb/include/lldb/lldb-forward.h | 3 +- lldb/include/lldb/lldb-private-interfaces.h | 2 + lldb/source/Commands/CMakeLists.txt | 1 + .../Commands/CommandObjectProtocolServer.cpp | 186 +++ .../Commands/CommandObjectProtocolServer.h| 25 ++ lldb/source/Core/CMakeLists.txt | 1 + lldb/source/Core/Debugger.cpp | 24 ++ lldb/source/Core/PluginManager.cpp| 32 ++ lldb/source/Core/ProtocolServer.cpp | 21 ++ .../source/Interpreter/CommandInterpreter.cpp | 2 + lldb/source/Plugins/CMakeLists.txt| 4 + lldb/source/Plugins/Protocol/CMakeLists.txt | 1 + .../Plugins/Protocol/MCP/CMakeLists.txt | 13 + lldb/source/Plugins/Protocol/MCP/MCPError.cpp | 34 ++ lldb/source/Plugins/Protocol/MCP/MCPError.h | 33 ++ lldb/source/Plugins/Protocol/MCP/Protocol.cpp | 203 lldb/source/Plugins/Protocol/MCP/Protocol.h | 128 .../Protocol/MCP/ProtocolServerMCP.cpp| 306 ++ .../Plugins/Protocol/MCP/ProtocolServerMCP.h | 94 ++ lldb/source/Plugins/Protocol/MCP/Tool.cpp | 70 lldb/source/Plugins/Protocol/MCP/Tool.h | 55 lldb/unittests/CMakeLists.txt | 4 + lldb/unittests/DAP/ProtocolTypesTest.cpp | 34 +- lldb/unittests/Protocol/CMakeLists.txt| 12 + .../Protocol/ProtocolMCPServerTest.cpp| 195 +++ lldb/unittests/Protocol/ProtocolMCPTest.cpp | 135 lldb/unittests/TestingSupport/TestUtilities.h | 9 + 33 files changed, 1665 insertions(+), 21 deletions(-) create mode 100644 lldb/include/lldb/Core/ProtocolServer.h create mode 100644 lldb/source/Commands/CommandObjectProtocolServer.cpp create mode 100644 lldb/source/Commands/CommandObjectProtocolServer.h create mode 100644 lldb/source/Core/ProtocolServer.cpp create mode 100644 lldb/source/Plugins/Protocol/CMakeLists.txt create mode 100644 lldb/source/Plugins/Protocol/MCP/CMakeLists.txt create mode 100644 lldb/source/Plugins/Protocol/MCP/MCPError.cpp create mode 100644 lldb/source/Plugins/Protocol/MCP/MCPError.h create mode 100644 lldb/source/Plugins/Protocol/MCP/Protocol.cpp create mode 100644 lldb/source/Plugins/Protocol/MCP/Protocol.h create mode 100644 lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.cpp create mode 100644 lldb/source/Plugins/Protocol/MCP/ProtocolServerMCP.h create mode 100644 lldb/source/Plugins/Protocol/MCP/Tool.cpp create mode 100644 lldb/source/Plugins/Protocol/MCP/Tool.h create mode 100644 lldb/unittests/Protocol/CMakeLists.txt create mode 100644 lldb/unittests/Protocol/ProtocolMCPServerTest.cpp create mode 100644 lldb/unittests/Protocol/ProtocolMCPTest.cpp diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 37b823feb584b..8c30b6e09d2c7 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -67,6 +67,7 @@ add_optional_dependency(LLDB_ENABLE_FBSDVMCORE "Enable libfbsdvmcore support in option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON) option(LLDB_BUILD_FRAMEWORK "Build LLDB.framework (Darwin only)" OFF) +option(LLDB_ENABLE_PROTOCOL_SERVERS "Enable protocol servers (e.g. MCP) in LLDB" ON) option(LLDB_NO_INSTALL_DEFAULT_RPATH "Disable default RPATH settings in binaries" OFF) option(LLDB_USE_SYSTEM_DEBUGSERVER "Use the system's debugserver for testing (Darwin only)." OFF) option(LLDB_SKIP_STRIP "Whether to skip stripping of binaries when installing lldb." OFF) diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index d73aba1e3ce58..0f6659d1a0bf7 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -598,6 +598,10 @@ class Debugger : public std::enable_shared_from_this, void FlushProcessOutput(Process &process, bool flush_stdout, bool flush_stderr); + void AddProtocolServer(lldb::ProtocolServerSP protocol_server_sp); + void RemoveProtocolServer(lldb::ProtocolServerSP protocol_server_sp); + lldb::ProtocolServerSP GetProtocolServer(llvm::StringRef protocol) const; + SourceManager::SourceFileCache &GetSourceFileCache() { return m_source_file_cache; } @@ -768,6 +772,8 @@ class Debugg
[Lldb-commits] [lldb] [lldb] move XcodeSDK's sysroot into a separate class (PR #144396)
charles-zablit wrote: > Is there a follow-up PR already up? Not yet, the original motivation is this issue on the Swift forums and more specifically this comment: https://forums.swift.org/t/lldb-crashes-during-vs-code-debug-session-on-windows-10/79902/10 `GetSDKPathFromDebugInfo` is not implemented for Windows which prints a non fatal error on non Darwin systems. We want to resolve the SDKs on Windows, which could be `Windows.sdk` or `Android.sdk`. https://github.com/llvm/llvm-project/pull/144396 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Use structured types for stepInTargets request (PR #144072)
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/144072 >From c4d909a9bb25983a955254956d3f0dab2ecc284f Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Thu, 12 Jun 2025 12:48:24 +0100 Subject: [PATCH 1/2] [lldb-dap] Use structured types for stepInTargets request --- .../test/tools/lldb-dap/dap_server.py | 2 +- .../stepInTargets/TestDAP_stepInTargets.py| 44 lldb/tools/lldb-dap/EventHelper.cpp | 5 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 13 +- .../Handler/StepInTargetsRequestHandler.cpp | 200 +++--- .../lldb-dap/Protocol/ProtocolRequests.cpp| 10 + .../lldb-dap/Protocol/ProtocolRequests.h | 15 ++ .../tools/lldb-dap/Protocol/ProtocolTypes.cpp | 22 ++ lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 28 +++ lldb/unittests/DAP/ProtocolTypesTest.cpp | 20 ++ 10 files changed, 223 insertions(+), 136 deletions(-) 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 9786678aa53f9..baf2d4ae542ba 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 @@ -494,7 +494,7 @@ def wait_for_terminated(self, timeout: Optional[float] = None): raise ValueError("didn't get terminated event") return event_dict -def get_capability(self, key): +def get_capability(self, key: str): """Get a value for the given key if it there is a key/value pair in the capabilities reported by the adapter. """ diff --git a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py index 07acfe07c9ffc..51ccf2ccbdcad 100644 --- a/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py +++ b/lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py @@ -78,3 +78,47 @@ def test_basic(self): leaf_frame = self.dap_server.get_stackFrame() self.assertIsNotNone(leaf_frame, "expect a leaf frame") self.assertEqual(step_in_targets[1]["label"], leaf_frame["name"]) + +@skipIf(archs=no_match(["x86", "x86_64"])) +def test_supported_capability_x86_arch(self): +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.cpp" +bp_lines = [line_number(source, "// set breakpoint here")] +breakpoint_ids = self.set_source_breakpoints(source, bp_lines) +self.assertEqual( +len(breakpoint_ids), len(bp_lines), "expect correct number of breakpoints" +) +self.continue_to_breakpoints(breakpoint_ids) +is_supported = self.dap_server.get_capability("supportsStepInTargetsRequest") + +self.assertEqual( +is_supported, +True, +f"expect capability `stepInTarget` is supported with architecture {self.getArchitecture()}", +) +# clear breakpoints. +self.set_source_breakpoints(source, []) +self.continue_to_exit() + +@skipIf(archs=["x86", "x86_64"]) +def test_supported_capability_other_archs(self): +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +source = "main.cpp" +bp_lines = [line_number(source, "// set breakpoint here")] +breakpoint_ids = self.set_source_breakpoints(source, bp_lines) +self.assertEqual( +len(breakpoint_ids), len(bp_lines), "expect correct number of breakpoints" +) +self.continue_to_breakpoints(breakpoint_ids) +is_supported = self.dap_server.get_capability("supportsStepInTargetsRequest") + +self.assertEqual( +is_supported, +False, +f"expect capability `stepInTarget` is not supported with architecture {self.getArchitecture()}", +) +# clear breakpoints. +self.set_source_breakpoints(source, []) +self.continue_to_exit() diff --git a/lldb/tools/lldb-dap/EventHelper.cpp b/lldb/tools/lldb-dap/EventHelper.cpp index 9641f29698b10..364cc7ab4ef8c 100644 --- a/lldb/tools/lldb-dap/EventHelper.cpp +++ b/lldb/tools/lldb-dap/EventHelper.cpp @@ -44,6 +44,11 @@ void SendTargetBasedCapabilities(DAP &dap) { protocol::CapabilitiesEventBody body; + const llvm::StringRef target_triple = dap.target.GetTriple(); + if (target_triple.starts_with("x86")) +body.capabilities.supportedFeatures.insert( +protocol::eAdapterFeatureStepInTargetsRequest); + // We only support restarting launch requests not attach requests. if (dap.last_launch_request) body.capabilities.supportedFeatures.insert( diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h b/lldb/tools/lldb-dap/Handler/RequestHandler.h index d3f231589b54c..0ac8ca7c9a49e 100644 --- a/lldb/tools/lldb-dap/Handler/RequestHandler.h +++ b/lldb
[Lldb-commits] [lldb] [lldb] Add Model Context Protocol (MCP) support to LLDB (PR #143628)
https://github.com/ashgti approved this pull request. LGTM! I look forward to trying this out and iterating on this. https://github.com/llvm/llvm-project/pull/143628 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix FindProcessImpl() for iOS simulators (PR #139174)
JDevlieghere wrote: > 1. It seems to me the test binary `a.out` isn't running on the simulator > (doesn't appear in `platform process list`). Is this expected/intentional? I can definitely see the binary running: ``` jonas46758 0.0 0.0 410596000 22720 s000 SX2:43PM 0:00.09 /Users/jonas/llvm/build-ra/lldb-test-build.noindex/macosx/simulator/TestSimulatorPlatform.test_ios/a.out ``` If it's not showing up in the `platform process list` then maybe there's a bug in the implementation? https://github.com/llvm/llvm-project/pull/139174 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits