Author: Jonas Devlieghere Date: 2020-06-12T09:39:17-07:00 New Revision: 2b34632a5771488ea62a30fdfcfc9d45060a7389
URL: https://github.com/llvm/llvm-project/commit/2b34632a5771488ea62a30fdfcfc9d45060a7389 DIFF: https://github.com/llvm/llvm-project/commit/2b34632a5771488ea62a30fdfcfc9d45060a7389.diff LOG: [lldb/SymbolFile] Don't parse the whole line table for the support files Prior to my patch of using the LLVM line table parsing code, SymbolFileDWARF::ParseSupportFiles would only parse the line table prologues to get the file list for any files that could be in the line table. With the old behavior, if we found the file that someone is setting the breakpoint in in the support files list, we would get a valid index. If we didn't, we would not look any further. So someone sets a breakpoint one "MyFile.cpp:12" and if we find "MyFile.cpp" in the support file list for the compile unit, then and only then would we get the entire line table for that compile unit. With the current behavior, no matter what, we always fully parse the line table for all compile units any time any file and line breakpoint is set. This creates a serious problem when debugging a large DWARF in .o file project. This patch re-instates the old behavior. Unfortunately it means we might end up parsing to prologue twice, but I don't think that outweighs the cost of trying to cache/reuse it. Differential revision: https://reviews.llvm.org/D81589 Added: Modified: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 6f2444b698ce..d662dcba4cdd 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -162,18 +162,46 @@ ParseLLVMLineTable(lldb_private::DWARFContext &context, llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table = line.getOrParseLineTable( data, line_offset, ctx, nullptr, [&](llvm::Error e) { - LLDB_LOG_ERROR(log, std::move(e), - "SymbolFileDWARF::ParseLineTable failed to parse"); + LLDB_LOG_ERROR( + log, std::move(e), + "SymbolFileDWARF::ParseLineTable failed to parse: {0}"); }); if (!line_table) { LLDB_LOG_ERROR(log, line_table.takeError(), - "SymbolFileDWARF::ParseLineTable failed to parse"); + "SymbolFileDWARF::ParseLineTable failed to parse: {0}"); return nullptr; } return *line_table; } +static bool ParseLLVMLineTablePrologue(lldb_private::DWARFContext &context, + llvm::DWARFDebugLine::Prologue &prologue, + dw_offset_t line_offset, + dw_offset_t unit_offset) { + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); + bool success = true; + llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM(); + llvm::DWARFContext &ctx = context.GetAsLLVM(); + uint64_t offset = line_offset; + llvm::Error error = prologue.parse( + data, &offset, + [&](llvm::Error e) { + success = false; + LLDB_LOG_ERROR(log, std::move(e), + "SymbolFileDWARF::ParseSupportFiles failed to parse " + "line table prologue: {0}"); + }, + ctx, nullptr); + if (error) { + LLDB_LOG_ERROR(log, std::move(error), + "SymbolFileDWARF::ParseSupportFiles failed to parse line " + "table prologue: {0}"); + return false; + } + return success; +} + static llvm::Optional<std::string> GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx, llvm::StringRef compile_dir, FileSpec::Style style) { @@ -854,8 +882,24 @@ bool SymbolFileDWARF::ForEachExternalModule( bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit, FileSpecList &support_files) { - if (!comp_unit.GetLineTable()) - ParseLineTable(comp_unit); + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); + if (!dwarf_cu) + return false; + + dw_offset_t offset = dwarf_cu->GetLineTableOffset(); + if (offset == DW_INVALID_OFFSET) + return false; + + llvm::DWARFDebugLine::Prologue prologue; + if (!ParseLLVMLineTablePrologue(m_context, prologue, offset, + dwarf_cu->GetOffset())) + return false; + + comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue( + comp_unit.GetModule(), prologue, dwarf_cu->GetPathStyle(), + dwarf_cu->GetCompilationDirectory().GetCString())); + return true; } @@ -978,18 +1022,13 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { if (!dwarf_cu) return false; - const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly(); - if (!dwarf_cu_die) - return false; - - const dw_offset_t cu_line_offset = dwarf_cu_die.GetAttributeValueAsUnsigned( - DW_AT_stmt_list, DW_INVALID_OFFSET); - if (cu_line_offset == DW_INVALID_OFFSET) + dw_offset_t offset = dwarf_cu->GetLineTableOffset(); + if (offset == DW_INVALID_OFFSET) return false; llvm::DWARFDebugLine line; - const llvm::DWARFDebugLine::LineTable *line_table = ParseLLVMLineTable( - m_context, line, cu_line_offset, dwarf_cu->GetOffset()); + const llvm::DWARFDebugLine::LineTable *line_table = + ParseLLVMLineTable(m_context, line, offset, dwarf_cu->GetOffset()); if (!line_table) return false; @@ -1024,10 +1063,6 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { comp_unit.SetLineTable(line_table_up.release()); } - comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue( - comp_unit.GetModule(), line_table->Prologue, dwarf_cu->GetPathStyle(), - dwarf_cu->GetCompilationDirectory().GetCString())); - return true; } @@ -2387,7 +2422,7 @@ void SymbolFileDWARF::FindTypes( UpdateExternalModuleListIfNeeded(); for (const auto &pair : m_external_type_modules) - if (ModuleSP external_module_sp = pair.second) + if (ModuleSP external_module_sp = pair.second) if (SymbolFile *sym_file = external_module_sp->GetSymbolFile()) sym_file->FindTypes(name, parent_decl_ctx, max_matches, searched_symbol_files, types); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits