Skip to content

Commit 9258f3e

Browse files
authored
[lldb] Fix a crash when using .dwp files and make type lookup reliable with the index cache (#79544)
When using split DWARF with .dwp files we had an issue where sometimes the DWO file within the .dwp file would be parsed _before_ the skeleton compile unit. The DWO file expects to be able to always be able to get a link back to the skeleton compile unit. Prior to this fix, the only time the skeleton compile unit backlink would get set, was if the unit headers for the main executable have been parsed _and_ if the unit DIE was parsed in that DWARFUnit. This patch ensures that we can always get the skeleton compile unit for a DWO file by adding a function: ``` DWARFCompileUnit *DWARFUnit::GetSkeletonUnit(); ``` Prior to this fix DWARFUnit had some unsafe accessors that were used to store two different things: ``` void *DWARFUnit::GetUserData() const; void DWARFUnit::SetUserData(void *d); ``` This was used by SymbolFileDWARF to cache the `lldb_private::CompileUnit *` for a SymbolFileDWARF and was also used to store the `DWARFUnit *` for SymbolFileDWARFDwo. This patch clears up this unsafe usage by adding two separate accessors and ivars for this: ``` lldb_private::CompileUnit *DWARFUnit::GetLLDBCompUnit() const { return m_lldb_cu; } void DWARFUnit::SetLLDBCompUnit(lldb_private::CompileUnit *cu) { m_lldb_cu = cu; } DWARFCompileUnit *DWARFUnit::GetSkeletonUnit(); void DWARFUnit::SetSkeletonUnit(DWARFUnit *skeleton_unit); ``` This will stop anyone from calling `void *DWARFUnit::GetUserData() const;` and casting the value to an incorrect value. A crash could occur in `SymbolFileDWARF::GetCompUnitForDWARFCompUnit()` when the `non_dwo_cu`, which is a backlink to the skeleton compile unit, was not set and was NULL. There is an assert() in the code, and then the code just will kill the program if the assert isn't enabled because the code looked like: ``` if (dwarf_cu.IsDWOUnit()) { DWARFCompileUnit *non_dwo_cu = static_cast<DWARFCompileUnit *>(dwarf_cu.GetUserData()); assert(non_dwo_cu); return non_dwo_cu->GetSymbolFileDWARF().GetCompUnitForDWARFCompUnit( *non_dwo_cu); } ``` This is now fixed by calling the `DWARFUnit::GetSkeletonUnit()` which will correctly always get the skeleton compile uint for a DWO file regardless of if the skeleton unit headers have been parse or if the skeleton unit DIE wasn't parsed yet. To implement the ability to get the skeleton compile units, I added code the DWARFDebugInfo.cpp/.h that make a map of DWO ID -> skeleton DWARFUnit * that gets filled in for DWARF5 when the unit headers are parsed. The `DWARFUnit::GetSkeletonUnit()` will end up parsing the unit headers of the main executable to fill in this map if it already hasn't been done. For DWARF4 and earlier we maintain a separate map that gets filled in only for any DWARF4 compile units that have a DW_AT_dwo_id or DW_AT_gnu_dwo_id attributes. This is more expensive, so this is done lazily and in a thread safe manor. This allows us to be as efficient as possible when using DWARF5 and also be backward compatible with DWARF4 + split DWARF. There was also an issue that stopped type lookups from succeeding in `DWARFDIE SymbolFileDWARF::GetDIE(const DIERef &die_ref)` where it directly was accessing the `m_dwp_symfile` ivar without calling the accessor function that could end up needing to locate and load the .dwp file. This was fixed by calling the `SymbolFileDWARF::GetDwpSymbolFile()` accessor to ensure we always get a valid value back if we can find the .dwp file. Prior to this fix it was down which APIs were called and if any APIs were called that loaded the .dwp file, it worked fine, but it might not if no APIs were called that did cause it to get loaded. When we have valid debug info indexes and when the lldb index cache was enabled, this would cause this issue to show up more often. I modified an existing test case to test that all of this works correctly and doesn't crash.
1 parent 5d228ea commit 9258f3e

File tree

9 files changed

+263
-40
lines changed

9 files changed

+263
-40
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "DWARFDebugInfoEntry.h"
2525
#include "DWARFFormValue.h"
2626
#include "DWARFTypeUnit.h"
27+
#include "LogChannelDWARF.h"
2728

2829
using namespace lldb;
2930
using namespace lldb_private;
@@ -81,27 +82,90 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) {
8182
: m_context.getOrLoadDebugInfoData();
8283
lldb::offset_t offset = 0;
8384
while (data.ValidOffset(offset)) {
84-
llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract(
85-
m_dwarf, m_units.size(), data, section, &offset);
85+
const lldb::offset_t unit_header_offset = offset;
86+
llvm::Expected<DWARFUnitSP> expected_unit_sp =
87+
DWARFUnit::extract(m_dwarf, m_units.size(), data, section, &offset);
8688

87-
if (!unit_sp) {
88-
// FIXME: Propagate this error up.
89-
llvm::consumeError(unit_sp.takeError());
89+
if (!expected_unit_sp) {
90+
Log *log = GetLog(DWARFLog::DebugInfo);
91+
LLDB_LOG(log, "Unable to extract DWARFUnitHeader at {0:x}: {1}",
92+
unit_header_offset, llvm::toString(expected_unit_sp.takeError()));
9093
return;
9194
}
9295

96+
DWARFUnitSP unit_sp = *expected_unit_sp;
97+
9398
// If it didn't return an error, then it should be returning a valid Unit.
94-
assert(*unit_sp);
95-
m_units.push_back(*unit_sp);
96-
offset = (*unit_sp)->GetNextUnitOffset();
99+
assert((bool)unit_sp);
100+
101+
// Keep a map of DWO ID back to the skeleton units. Sometimes accelerator
102+
// table lookups can cause the DWO files to be accessed before the skeleton
103+
// compile unit is parsed, so we keep a map to allow us to match up the DWO
104+
// file to the back to the skeleton compile units.
105+
if (unit_sp->GetUnitType() == lldb_private::dwarf::DW_UT_skeleton) {
106+
if (std::optional<uint64_t> unit_dwo_id = unit_sp->GetHeaderDWOId())
107+
m_dwarf5_dwo_id_to_skeleton_unit[*unit_dwo_id] = unit_sp.get();
108+
}
97109

98-
if (auto *type_unit = llvm::dyn_cast<DWARFTypeUnit>(unit_sp->get())) {
110+
m_units.push_back(unit_sp);
111+
offset = unit_sp->GetNextUnitOffset();
112+
113+
if (auto *type_unit = llvm::dyn_cast<DWARFTypeUnit>(unit_sp.get())) {
99114
m_type_hash_to_unit_index.emplace_back(type_unit->GetTypeHash(),
100-
unit_sp.get()->GetID());
115+
unit_sp->GetID());
101116
}
102117
}
103118
}
104119

120+
DWARFUnit *DWARFDebugInfo::GetSkeletonUnit(DWARFUnit *dwo_unit) {
121+
// If this isn't a DWO unit, don't try and find the skeleton unit.
122+
if (!dwo_unit->IsDWOUnit())
123+
return nullptr;
124+
125+
auto dwo_id = dwo_unit->GetDWOId();
126+
if (!dwo_id.has_value())
127+
return nullptr;
128+
129+
// Parse the unit headers so that m_dwarf5_dwo_id_to_skeleton_unit is filled
130+
// in with all of the DWARF5 skeleton compile units DWO IDs since it is easy
131+
// to access the DWO IDs in the DWARFUnitHeader for each DWARFUnit.
132+
ParseUnitHeadersIfNeeded();
133+
134+
// Find the value in our cache and return it we we find it. This cache may
135+
// only contain DWARF5 units.
136+
auto iter = m_dwarf5_dwo_id_to_skeleton_unit.find(*dwo_id);
137+
if (iter != m_dwarf5_dwo_id_to_skeleton_unit.end())
138+
return iter->second;
139+
140+
// DWARF5 unit headers have the DWO ID and should have already been in the map
141+
// so if it wasn't found in the above find() call, then we didn't find it and
142+
// don't need to do the more expensive DWARF4 search.
143+
if (dwo_unit->GetVersion() >= 5)
144+
return nullptr;
145+
146+
// Parse all DWO IDs from all DWARF4 and earlier compile units that have DWO
147+
// IDs. It is more expensive to get the DWO IDs from DWARF4 compile units as
148+
// we need to parse the unit DIE and extract the DW_AT_dwo_id or
149+
// DW_AT_GNU_dwo_id attribute values, so do this only if we didn't find our
150+
// match above search and only for DWARF4 and earlier compile units.
151+
llvm::call_once(m_dwarf4_dwo_id_to_skeleton_unit_once_flag, [this]() {
152+
for (uint32_t i = 0, num = GetNumUnits(); i < num; ++i) {
153+
if (DWARFUnit *unit = GetUnitAtIndex(i)) {
154+
if (unit->GetVersion() < 5) {
155+
if (std::optional<uint64_t> unit_dwo_id = unit->GetDWOId())
156+
m_dwarf4_dwo_id_to_skeleton_unit[*unit_dwo_id] = unit;
157+
}
158+
}
159+
}
160+
});
161+
162+
// Search the DWARF4 DWO results that we parsed lazily.
163+
iter = m_dwarf4_dwo_id_to_skeleton_unit.find(*dwo_id);
164+
if (iter != m_dwarf4_dwo_id_to_skeleton_unit.end())
165+
return iter->second;
166+
return nullptr;
167+
}
168+
105169
void DWARFDebugInfo::ParseUnitHeadersIfNeeded() {
106170
llvm::call_once(m_units_once_flag, [&] {
107171
ParseUnitsFor(DIERef::Section::DebugInfo);

lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class DWARFDebugInfo {
3939
DWARFUnit *GetUnitContainingDIEOffset(DIERef::Section section,
4040
dw_offset_t die_offset);
4141
DWARFUnit *GetUnit(const DIERef &die_ref);
42+
DWARFUnit *GetSkeletonUnit(DWARFUnit *dwo_unit);
4243
DWARFTypeUnit *GetTypeUnitForHash(uint64_t hash);
4344
bool ContainsTypeUnits();
4445
DWARFDIE GetDIE(const DIERef &die_ref);
@@ -70,6 +71,9 @@ class DWARFDebugInfo {
7071
m_cu_aranges_up; // A quick address to compile unit table
7172

7273
std::vector<std::pair<uint64_t, uint32_t>> m_type_hash_to_unit_index;
74+
llvm::DenseMap<uint64_t, DWARFUnit *> m_dwarf5_dwo_id_to_skeleton_unit;
75+
llvm::DenseMap<uint64_t, DWARFUnit *> m_dwarf4_dwo_id_to_skeleton_unit;
76+
llvm::once_flag m_dwarf4_dwo_id_to_skeleton_unit_once_flag;
7377

7478
private:
7579
// All parsing needs to be done partially any managed by this class as

lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,12 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() {
9797
*m_dwo_id, m_first_die.GetOffset()));
9898
return; // Can't fetch the compile unit from the dwo file.
9999
}
100-
dwo_cu->SetUserData(this);
100+
// If the skeleton compile unit gets its unit DIE parsed first, then this
101+
// will fill in the DWO file's back pointer to this skeleton compile unit.
102+
// If the DWO files get parsed on their own first the skeleton back link
103+
// can be done manually in DWARFUnit::GetSkeletonCompileUnit() which will
104+
// do a reverse lookup and cache the result.
105+
dwo_cu->SetSkeletonUnit(this);
101106

102107
DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
103108
if (!dwo_cu_die.IsValid()) {
@@ -702,9 +707,25 @@ uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) {
702707

703708
uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; }
704709

705-
void *DWARFUnit::GetUserData() const { return m_user_data; }
710+
DWARFCompileUnit *DWARFUnit::GetSkeletonUnit() {
711+
if (m_skeleton_unit == nullptr && IsDWOUnit()) {
712+
SymbolFileDWARFDwo *dwo =
713+
llvm::dyn_cast_or_null<SymbolFileDWARFDwo>(&GetSymbolFileDWARF());
714+
// Do a reverse lookup if the skeleton compile unit wasn't set.
715+
if (dwo)
716+
m_skeleton_unit = dwo->GetBaseSymbolFile().GetSkeletonUnit(this);
717+
}
718+
return llvm::dyn_cast_or_null<DWARFCompileUnit>(m_skeleton_unit);
719+
}
706720

707-
void DWARFUnit::SetUserData(void *d) { m_user_data = d; }
721+
void DWARFUnit::SetSkeletonUnit(DWARFUnit *skeleton_unit) {
722+
// If someone is re-setting the skeleton compile unit backlink, make sure
723+
// it is setting it to a valid value when it wasn't valid, or if the
724+
// value in m_skeleton_unit was valid, it should be the same value.
725+
assert(skeleton_unit);
726+
assert(m_skeleton_unit == nullptr || m_skeleton_unit == skeleton_unit);
727+
m_skeleton_unit = skeleton_unit;
728+
}
708729

709730
bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() {
710731
return GetProducer() != eProducerLLVMGCC;

lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,14 @@ class DWARFUnit : public UserID {
9898
virtual ~DWARFUnit();
9999

100100
bool IsDWOUnit() { return m_is_dwo; }
101+
/// Get the DWO ID from the DWARFUnitHeader for DWARF5, or from the unit DIE's
102+
/// DW_AT_dwo_id or DW_AT_GNU_dwo_id for DWARF4 and earlier.
101103
std::optional<uint64_t> GetDWOId();
102-
104+
/// Get the DWO ID from the DWARFUnitHeader only. DWARF5 skeleton units have
105+
/// the DWO ID in the compile unit header and we sometimes only want to access
106+
/// this cheap value without causing the more expensive attribute fetches that
107+
/// GetDWOId() uses.
108+
std::optional<uint64_t> GetHeaderDWOId() { return m_header.GetDWOId(); }
103109
void ExtractUnitDIEIfNeeded();
104110
void ExtractUnitDIENoDwoIfNeeded();
105111
void ExtractDIEsIfNeeded();
@@ -198,9 +204,21 @@ class DWARFUnit : public UserID {
198204

199205
static uint8_t GetDefaultAddressSize();
200206

201-
void *GetUserData() const;
207+
lldb_private::CompileUnit *GetLLDBCompUnit() const { return m_lldb_cu; }
208+
209+
void SetLLDBCompUnit(lldb_private::CompileUnit *cu) { m_lldb_cu = cu; }
210+
211+
/// Get the skeleton compile unit for a DWO file.
212+
///
213+
/// We need to keep track of the skeleton compile unit for a DWO file so
214+
/// we can access it. Sometimes this value is cached when the skeleton
215+
/// compile unit is first parsed, but if a .dwp file parses all of the
216+
/// DWARFUnits in the file, the skeleton compile unit might not have been
217+
/// parsed yet, to there might not be a backlink. This accessor handles
218+
/// both cases correctly and avoids crashes.
219+
DWARFCompileUnit *GetSkeletonUnit();
202220

203-
void SetUserData(void *d);
221+
void SetSkeletonUnit(DWARFUnit *skeleton_unit);
204222

205223
bool Supports_DW_AT_APPLE_objc_complete_type();
206224

@@ -336,7 +354,9 @@ class DWARFUnit : public UserID {
336354
std::shared_ptr<DWARFUnit> m_dwo;
337355
DWARFUnitHeader m_header;
338356
const llvm::DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr;
339-
void *m_user_data = nullptr;
357+
lldb_private::CompileUnit *m_lldb_cu = nullptr;
358+
// If this is a DWO file, we have a backlink to our skeleton compile unit.
359+
DWARFUnit *m_skeleton_unit = nullptr;
340360
// The compile unit debug information entry item
341361
DWARFDebugInfoEntry::collection m_die_array;
342362
mutable llvm::sys::RWMutex m_die_array_mutex;

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,8 @@ DWARFCompileUnit *SymbolFileDWARF::GetDWARFCompileUnit(CompileUnit *comp_unit) {
722722

723723
// The compile unit ID is the index of the DWARF unit.
724724
DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(comp_unit->GetID());
725-
if (dwarf_cu && dwarf_cu->GetUserData() == nullptr)
726-
dwarf_cu->SetUserData(comp_unit);
725+
if (dwarf_cu && dwarf_cu->GetLLDBCompUnit() == nullptr)
726+
dwarf_cu->SetLLDBCompUnit(comp_unit);
727727

728728
// It must be DWARFCompileUnit when it created a CompileUnit.
729729
return llvm::cast_or_null<DWARFCompileUnit>(dwarf_cu);
@@ -771,15 +771,15 @@ static const char *GetDWOName(DWARFCompileUnit &dwarf_cu,
771771

772772
lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
773773
CompUnitSP cu_sp;
774-
CompileUnit *comp_unit = (CompileUnit *)dwarf_cu.GetUserData();
774+
CompileUnit *comp_unit = dwarf_cu.GetLLDBCompUnit();
775775
if (comp_unit) {
776776
// We already parsed this compile unit, had out a shared pointer to it
777777
cu_sp = comp_unit->shared_from_this();
778778
} else {
779779
if (GetDebugMapSymfile()) {
780780
// Let the debug map create the compile unit
781781
cu_sp = m_debug_map_symfile->GetCompileUnit(this, dwarf_cu);
782-
dwarf_cu.SetUserData(cu_sp.get());
782+
dwarf_cu.SetLLDBCompUnit(cu_sp.get());
783783
} else {
784784
ModuleSP module_sp(m_objfile_sp->GetModule());
785785
if (module_sp) {
@@ -792,7 +792,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
792792
*GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language,
793793
eLazyBoolCalculate, std::move(support_files));
794794

795-
dwarf_cu.SetUserData(cu_sp.get());
795+
dwarf_cu.SetLLDBCompUnit(cu_sp.get());
796796

797797
SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp);
798798
};
@@ -1675,20 +1675,20 @@ Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,
16751675

16761676
CompileUnit *
16771677
SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu) {
1678+
16781679
if (dwarf_cu.IsDWOUnit()) {
1679-
DWARFCompileUnit *non_dwo_cu =
1680-
static_cast<DWARFCompileUnit *>(dwarf_cu.GetUserData());
1680+
DWARFCompileUnit *non_dwo_cu = dwarf_cu.GetSkeletonUnit();
16811681
assert(non_dwo_cu);
16821682
return non_dwo_cu->GetSymbolFileDWARF().GetCompUnitForDWARFCompUnit(
16831683
*non_dwo_cu);
16841684
}
16851685
// Check if the symbol vendor already knows about this compile unit?
1686-
if (dwarf_cu.GetUserData() == nullptr) {
1687-
// The symbol vendor doesn't know about this compile unit, we need to parse
1688-
// and add it to the symbol vendor object.
1689-
return ParseCompileUnit(dwarf_cu).get();
1690-
}
1691-
return static_cast<CompileUnit *>(dwarf_cu.GetUserData());
1686+
CompileUnit *lldb_cu = dwarf_cu.GetLLDBCompUnit();
1687+
if (lldb_cu)
1688+
return lldb_cu;
1689+
// The symbol vendor doesn't know about this compile unit, we need to parse
1690+
// and add it to the symbol vendor object.
1691+
return ParseCompileUnit(dwarf_cu).get();
16921692
}
16931693

16941694
void SymbolFileDWARF::GetObjCMethods(
@@ -1750,7 +1750,7 @@ SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
17501750
}
17511751

17521752
if (*file_index == DIERef::k_file_index_mask)
1753-
symbol_file = m_dwp_symfile.get(); // DWP case
1753+
symbol_file = GetDwpSymbolFile().get(); // DWP case
17541754
else
17551755
symbol_file = this->DebugInfo()
17561756
.GetUnitAtIndex(*die_ref.file_index())
@@ -1785,6 +1785,10 @@ std::optional<uint64_t> SymbolFileDWARF::GetDWOId() {
17851785
return {};
17861786
}
17871787

1788+
DWARFUnit *SymbolFileDWARF::GetSkeletonUnit(DWARFUnit *dwo_unit) {
1789+
return DebugInfo().GetSkeletonUnit(dwo_unit);
1790+
}
1791+
17881792
std::shared_ptr<SymbolFileDWARFDwo>
17891793
SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
17901794
DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) {

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,17 @@ class SymbolFileDWARF : public SymbolFileCommon {
252252
/// If this is a DWARF object with a single CU, return its DW_AT_dwo_id.
253253
std::optional<uint64_t> GetDWOId();
254254

255+
/// Given a DWO DWARFUnit, find the corresponding skeleton DWARFUnit
256+
/// in the main symbol file. DWP files can have their DWARFUnits
257+
/// parsed without the skeleton compile units having been parsed, so
258+
/// sometimes we need to find the skeleton compile unit for a DWO
259+
/// DWARFUnit so we can fill in this link. Currently unless the
260+
/// skeleton compile unit has been parsed _and_ the Unit DIE has been
261+
/// parsed, the DWO unit will not have a backward link setup correctly
262+
/// which was causing crashes due to an assertion that was firing
263+
/// in SymbolFileDWARF::GetCompUnitForDWARFCompUnit().
264+
DWARFUnit *GetSkeletonUnit(DWARFUnit *dwo_unit);
265+
255266
static bool DIEInDeclContext(const CompilerDeclContext &parent_decl_ctx,
256267
const DWARFDIE &die,
257268
bool only_root_namespaces = false);

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,22 @@ void SymbolFileDWARFDwo::FindGlobalVariables(
160160
GetBaseSymbolFile().FindGlobalVariables(name, parent_decl_ctx, max_matches,
161161
variables);
162162
}
163+
164+
bool SymbolFileDWARFDwo::GetDebugInfoIndexWasLoadedFromCache() const {
165+
return GetBaseSymbolFile().GetDebugInfoIndexWasLoadedFromCache();
166+
}
167+
void SymbolFileDWARFDwo::SetDebugInfoIndexWasLoadedFromCache() {
168+
GetBaseSymbolFile().SetDebugInfoIndexWasLoadedFromCache();
169+
}
170+
bool SymbolFileDWARFDwo::GetDebugInfoIndexWasSavedToCache() const {
171+
return GetBaseSymbolFile().GetDebugInfoIndexWasSavedToCache();
172+
}
173+
void SymbolFileDWARFDwo::SetDebugInfoIndexWasSavedToCache() {
174+
GetBaseSymbolFile().SetDebugInfoIndexWasSavedToCache();
175+
}
176+
bool SymbolFileDWARFDwo::GetDebugInfoHadFrameVariableErrors() const {
177+
return GetBaseSymbolFile().GetDebugInfoHadFrameVariableErrors();
178+
}
179+
void SymbolFileDWARFDwo::SetDebugInfoHadFrameVariableErrors() {
180+
return GetBaseSymbolFile().SetDebugInfoHadFrameVariableErrors();
181+
}

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ class SymbolFileDWARFDwo : public SymbolFileDWARF {
5858
uint32_t max_matches,
5959
VariableList &variables) override;
6060

61+
SymbolFileDWARF &GetBaseSymbolFile() const { return m_base_symbol_file; }
62+
63+
bool GetDebugInfoIndexWasLoadedFromCache() const override;
64+
void SetDebugInfoIndexWasLoadedFromCache() override;
65+
bool GetDebugInfoIndexWasSavedToCache() const override;
66+
void SetDebugInfoIndexWasSavedToCache() override;
67+
bool GetDebugInfoHadFrameVariableErrors() const override;
68+
void SetDebugInfoHadFrameVariableErrors() override;
69+
6170
protected:
6271
DIEToTypePtr &GetDIEToType() override;
6372

@@ -77,8 +86,6 @@ class SymbolFileDWARFDwo : public SymbolFileDWARF {
7786
ConstString type_name,
7887
bool must_be_implementation) override;
7988

80-
SymbolFileDWARF &GetBaseSymbolFile() const { return m_base_symbol_file; }
81-
8289
/// If this file contains exactly one compile unit, this function will return
8390
/// it. Otherwise it returns nullptr.
8491
DWARFCompileUnit *FindSingleCompileUnit();

0 commit comments

Comments
 (0)