Skip to content

Commit

Permalink
[lldb][SymbolFileDWARFDebugMap] Introduce enum to indicate whether to…
Browse files Browse the repository at this point in the history
… continue iteration of object files (llvm#87344)

This patch introduces a new `IterationMarker` enum (happy to take
alternative name suggestions), which callbacks, like the one in
`SymbolFileDWARFDebugMap::ForEachSymbolFile`, can return in order to
indicate whether the caller should continue iterating or bail.

For now this patch just changes the `ForEachSymbolFile` callback to use
this new enum. In the future we could change the various
`DWARFIndex::GetXXX` callbacks to do the same.

This makes the callbacks easier to read and hopefully reduces the chance
of bugs like llvm#87177.
  • Loading branch information
Michael137 authored Apr 2, 2024
1 parent 84ae8cb commit e61d6b7
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 40 deletions.
7 changes: 7 additions & 0 deletions lldb/include/lldb/lldb-private-enumerations.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,13 @@ enum LoadDependentFiles {
eLoadDependentsNo,
};

/// Useful for callbacks whose return type indicates
/// whether to continue iteration or short-circuit.
enum class IterationAction {
Continue = 0,
Stop,
};

inline std::string GetStatDescription(lldb_private::StatisticKind K) {
switch (K) {
case StatisticKind::ExpressionSuccessful:
Expand Down
75 changes: 39 additions & 36 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
#include "lldb/lldb-private-enumerations.h"

#include <memory>
#include <optional>
Expand Down Expand Up @@ -803,13 +804,13 @@ SymbolFileDWARFDebugMap::GetDynamicArrayInfoForUID(
bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) {
bool success = false;
if (compiler_type) {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
if (oso_dwarf->HasForwardDeclForCompilerType(compiler_type)) {
oso_dwarf->CompleteType(compiler_type);
success = true;
return true;
return IterationAction::Stop;
}
return false;
return IterationAction::Continue;
});
}
return success;
Expand Down Expand Up @@ -915,7 +916,7 @@ void SymbolFileDWARFDebugMap::FindGlobalVariables(
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t total_matches = 0;

ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
const uint32_t old_size = variables.GetSize();
oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
variables);
Expand All @@ -925,18 +926,18 @@ void SymbolFileDWARFDebugMap::FindGlobalVariables(

// Are we getting all matches?
if (max_matches == UINT32_MAX)
return false; // Yep, continue getting everything
return IterationAction::Continue; // Yep, continue getting everything

// If we have found enough matches, lets get out
if (max_matches >= total_matches)
return true;
return IterationAction::Stop;

// Update the max matches for any subsequent calls to find globals in any
// other object files with DWARF
max_matches -= oso_matches;
}

return false;
return IterationAction::Continue;
});
}

Expand All @@ -945,7 +946,7 @@ void SymbolFileDWARFDebugMap::FindGlobalVariables(
VariableList &variables) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
uint32_t total_matches = 0;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
const uint32_t old_size = variables.GetSize();
oso_dwarf->FindGlobalVariables(regex, max_matches, variables);

Expand All @@ -955,18 +956,18 @@ void SymbolFileDWARFDebugMap::FindGlobalVariables(

// Are we getting all matches?
if (max_matches == UINT32_MAX)
return false; // Yep, continue getting everything
return IterationAction::Continue; // Yep, continue getting everything

// If we have found enough matches, lets get out
if (max_matches >= total_matches)
return true;
return IterationAction::Stop;

// Update the max matches for any subsequent calls to find globals in any
// other object files with DWARF
max_matches -= oso_matches;
}

return false;
return IterationAction::Continue;
});
}

Expand Down Expand Up @@ -1071,15 +1072,15 @@ void SymbolFileDWARFDebugMap::FindFunctions(
LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
lookup_info.GetLookupName().GetCString());

ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
uint32_t sc_idx = sc_list.GetSize();
oso_dwarf->FindFunctions(lookup_info, parent_decl_ctx, include_inlines,
sc_list);
if (!sc_list.IsEmpty()) {
RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
sc_idx);
}
return false;
return IterationAction::Continue;
});
}

Expand All @@ -1090,15 +1091,15 @@ void SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
regex.GetText().str().c_str());

ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
uint32_t sc_idx = sc_list.GetSize();

oso_dwarf->FindFunctions(regex, include_inlines, sc_list);
if (!sc_list.IsEmpty()) {
RemoveFunctionsWithModuleNotEqualTo(m_objfile_sp->GetModule(), sc_list,
sc_idx);
}
return false;
return IterationAction::Continue;
});
}

Expand All @@ -1121,9 +1122,9 @@ void SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
}
} else {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
return false;
return IterationAction::Continue;
});
}
}
Expand All @@ -1141,9 +1142,9 @@ SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(
TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext(
const DWARFDIE &die) {
TypeSP type_sp;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die);
return ((bool)type_sp);
return type_sp ? IterationAction::Stop : IterationAction::Continue;
});
return type_sp;
}
Expand All @@ -1152,13 +1153,13 @@ bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
SymbolFileDWARF *skip_dwarf_oso) {
if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
if (skip_dwarf_oso != oso_dwarf &&
oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(nullptr)) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
return true;
return IterationAction::Stop;
}
return false;
return IterationAction::Continue;
});
}
return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
Expand Down Expand Up @@ -1217,10 +1218,10 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
if (!must_be_implementation) {
TypeSP type_sp;

ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
die, type_name, must_be_implementation);
return (bool)type_sp;
return type_sp ? IterationAction::Stop : IterationAction::Continue;
});

return type_sp;
Expand All @@ -1231,9 +1232,10 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
void SymbolFileDWARFDebugMap::FindTypes(const TypeQuery &query,
TypeResults &results) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
oso_dwarf->FindTypes(query, results);
return results.Done(query); // Keep iterating if we aren't done.
return results.Done(query) ? IterationAction::Stop
: IterationAction::Continue;
});
}

Expand All @@ -1243,23 +1245,24 @@ CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompilerDeclContext matching_namespace;

ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
matching_namespace =
oso_dwarf->FindNamespace(name, parent_decl_ctx, only_root_namespaces);

return (bool)matching_namespace;
return matching_namespace ? IterationAction::Stop
: IterationAction::Continue;
});

return matching_namespace;
}

void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) {
ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) {
oso_dwarf->DumpClangAST(s);
// The underlying assumption is that DumpClangAST(...) will obtain the
// AST from the underlying TypeSystem and therefore we only need to do
// this once and can stop after the first iteration hence we return true.
return true;
return IterationAction::Stop;
});
}

Expand Down Expand Up @@ -1389,9 +1392,9 @@ SymbolFileDWARFDebugMap::GetCompilerContextForUID(lldb::user_id_t type_uid) {

void SymbolFileDWARFDebugMap::ParseDeclsForContext(
lldb_private::CompilerDeclContext decl_ctx) {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
oso_dwarf->ParseDeclsForContext(decl_ctx);
return false; // Keep iterating
return IterationAction::Continue;
});
}

Expand Down Expand Up @@ -1519,14 +1522,14 @@ SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data,

ModuleList SymbolFileDWARFDebugMap::GetDebugInfoModules() {
ModuleList oso_modules;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
ObjectFile *oso_objfile = oso_dwarf->GetObjectFile();
if (oso_objfile) {
ModuleSP module_sp = oso_objfile->GetModule();
if (module_sp)
oso_modules.Append(module_sp);
}
return false; // Keep iterating
return IterationAction::Continue;
});
return oso_modules;
}
Expand Down Expand Up @@ -1579,8 +1582,8 @@ Status SymbolFileDWARFDebugMap::CalculateFrameVariableError(StackFrame &frame) {
void SymbolFileDWARFDebugMap::GetCompileOptions(
std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) {

ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
oso_dwarf->GetCompileOptions(args);
return false;
return IterationAction::Continue;
});
}
10 changes: 6 additions & 4 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "UniqueDWARFASTType.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/lldb-private-enumerations.h"

class DWARFASTParserClang;

Expand Down Expand Up @@ -233,13 +234,14 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {

SymbolFileDWARF *GetSymbolFileByOSOIndex(uint32_t oso_idx);

// If closure returns "false", iteration continues. If it returns
// "true", iteration terminates.
void ForEachSymbolFile(std::function<bool(SymbolFileDWARF *)> closure) {
/// If closure returns \ref IterationAction::Continue, iteration
/// continues. Otherwise, iteration terminates.
void
ForEachSymbolFile(std::function<IterationAction(SymbolFileDWARF *)> closure) {
for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size();
oso_idx < num_oso_idxs; ++oso_idx) {
if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx)) {
if (closure(oso_dwarf))
if (closure(oso_dwarf) == IterationAction::Stop)
return;
}
}
Expand Down

0 comments on commit e61d6b7

Please sign in to comment.