Skip to content

Commit

Permalink
[lldb/SymbolFile] Don't parse the whole line table for the support files
Browse files Browse the repository at this point in the history
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

(cherry picked from commit 2b34632)
  • Loading branch information
JDevlieghere committed Jun 12, 2020
1 parent 8880a4c commit b643e1d
Showing 1 changed file with 54 additions and 19 deletions.
73 changes: 54 additions & 19 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Expand Up @@ -169,18 +169,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) {
Expand Down Expand Up @@ -919,8 +947,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;
}

Expand Down Expand Up @@ -1040,18 +1084,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;
Expand Down Expand Up @@ -1086,10 +1125,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;
}

Expand Down Expand Up @@ -2550,7 +2585,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);
Expand Down

0 comments on commit b643e1d

Please sign in to comment.