@@ -44,22 +44,21 @@ void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
44
44
DWARFSectionKind SectionKind) {
45
45
const DWARFObject &D = C.getDWARFObj ();
46
46
addUnitsImpl (C, D, Section, C.getDebugAbbrev (), &D.getRangesSection (),
47
- &D.getLocSection (), D.getStrSection (),
48
- D.getStrOffsetsSection (), &D.getAddrSection (),
49
- D.getLineSection (), D.isLittleEndian (), false , false ,
50
- SectionKind);
47
+ &D.getLocSection (), D.getStrSection (), D.getStrOffsetsSection (),
48
+ &D.getAddrSection (), D.getLineSection (), D.isLittleEndian (),
49
+ false , false , SectionKind);
51
50
}
52
51
53
52
void DWARFUnitVector::addUnitsForDWOSection (DWARFContext &C,
54
53
const DWARFSection &DWOSection,
55
54
DWARFSectionKind SectionKind,
56
55
bool Lazy) {
57
56
const DWARFObject &D = C.getDWARFObj ();
58
- addUnitsImpl (C, D, DWOSection, C.getDebugAbbrevDWO (), &D. getRangesDWOSection (),
59
- &D.getLocDWOSection (), D. getStrDWOSection (),
60
- D.getStrOffsetsDWOSection (), &D. getAddrSection (),
61
- D. getLineDWOSection (), C.isLittleEndian (), true , Lazy ,
62
- SectionKind);
57
+ addUnitsImpl (C, D, DWOSection, C.getDebugAbbrevDWO (),
58
+ &D.getRangesDWOSection (), &D. getLocDWOSection (),
59
+ D.getStrDWOSection (), D. getStrOffsetsDWOSection (),
60
+ &D. getAddrSection (), D. getLineDWOSection (), C.isLittleEndian (),
61
+ true , Lazy, SectionKind);
63
62
}
64
63
65
64
void DWARFUnitVector::addUnitsImpl (
@@ -107,12 +106,12 @@ void DWARFUnitVector::addUnitsImpl(
107
106
std::unique_ptr<DWARFUnit> U;
108
107
if (Header.isTypeUnit ())
109
108
U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
110
- RS, LocSection, SS, SOS, AOS, LS,
111
- LE, IsDWO, *this );
109
+ RS, LocSection, SS, SOS, AOS, LS,
110
+ LE, IsDWO, *this );
112
111
else
113
- U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
114
- DA, RS, LocSection, SS, SOS,
115
- AOS, LS, LE, IsDWO, *this );
112
+ U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header, DA,
113
+ RS, LocSection, SS, SOS, AOS, LS ,
114
+ LE, IsDWO, *this );
116
115
return U;
117
116
};
118
117
}
@@ -496,8 +495,12 @@ void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
496
495
}
497
496
498
497
Error DWARFUnit::tryExtractDIEsIfNeeded (bool CUDieOnly) {
499
- if ((CUDieOnly && !DieArray.empty ()) ||
500
- DieArray.size () > 1 )
498
+ // Acquire the FreeDIEsMutex recursive lock to prevent a different thread
499
+ // from freeing the DIE arrays while they're being extracted. It needs to
500
+ // be recursive, as there is a potentially recursive path through
501
+ // determineStringOffsetsTableContribution.
502
+ std::lock_guard<std::recursive_mutex> FreeLock (FreeDIEsMutex);
503
+ if ((CUDieOnly && !DieArray.empty ()) || DieArray.size () > 1 )
501
504
return Error::success (); // Already parsed.
502
505
503
506
bool HasCUDie = !DieArray.empty ();
@@ -652,7 +655,13 @@ bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
652
655
return true ;
653
656
}
654
657
655
- void DWARFUnit::clearDIEs (bool KeepCUDie) {
658
+ void DWARFUnit::clearDIEs (bool KeepCUDie, bool KeepDWODies) {
659
+ // We need to acquire the FreeDIEsMutex lock because we are
660
+ // going to free the DIEs, when other threads might be trying to create them.
661
+ std::lock_guard<std::recursive_mutex> FreeLock (FreeDIEsMutex);
662
+ if (!KeepDWODies && DWO) {
663
+ DWO->clearDIEs (KeepCUDie, KeepDWODies);
664
+ }
656
665
// Do not use resize() + shrink_to_fit() to free memory occupied by dies.
657
666
// shrink_to_fit() is a *non-binding* request to reduce capacity() to size().
658
667
// It depends on the implementation whether the request is fulfilled.
@@ -868,9 +877,8 @@ DWARFDie DWARFUnit::getVariableForAddress(uint64_t Address) {
868
877
return R->second .second ;
869
878
}
870
879
871
- void
872
- DWARFUnit::getInlinedChainForAddress (uint64_t Address,
873
- SmallVectorImpl<DWARFDie> &InlinedChain) {
880
+ void DWARFUnit::getInlinedChainForAddress (
881
+ uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) {
874
882
assert (InlinedChain.empty ());
875
883
// Try to look for subprogram DIEs in the DWO file.
876
884
parseDWO ();
@@ -886,7 +894,7 @@ DWARFUnit::getInlinedChainForAddress(uint64_t Address,
886
894
}
887
895
if (SubroutineDIE.getTag () == DW_TAG_inlined_subroutine)
888
896
InlinedChain.push_back (SubroutineDIE);
889
- SubroutineDIE = SubroutineDIE.getParent ();
897
+ SubroutineDIE = SubroutineDIE.getParent ();
890
898
}
891
899
}
892
900
@@ -1087,18 +1095,22 @@ StrOffsetsContributionDescriptor::validateContributionSize(
1087
1095
if (ValidationSize >= Size)
1088
1096
if (DA.isValidOffsetForDataOfSize ((uint32_t )Base, ValidationSize))
1089
1097
return *this ;
1090
- return createStringError (errc::invalid_argument, " length exceeds section size" );
1098
+ return createStringError (errc::invalid_argument,
1099
+ " length exceeds section size" );
1091
1100
}
1092
1101
1093
1102
// Look for a DWARF64-formatted contribution to the string offsets table
1094
1103
// starting at a given offset and record it in a descriptor.
1095
1104
static Expected<StrOffsetsContributionDescriptor>
1096
1105
parseDWARF64StringOffsetsTableHeader (DWARFDataExtractor &DA, uint64_t Offset) {
1097
1106
if (!DA.isValidOffsetForDataOfSize (Offset, 16 ))
1098
- return createStringError (errc::invalid_argument, " section offset exceeds section size" );
1107
+ return createStringError (errc::invalid_argument,
1108
+ " section offset exceeds section size" );
1099
1109
1100
1110
if (DA.getU32 (&Offset) != dwarf::DW_LENGTH_DWARF64)
1101
- return createStringError (errc::invalid_argument, " 32 bit contribution referenced from a 64 bit unit" );
1111
+ return createStringError (
1112
+ errc::invalid_argument,
1113
+ " 32 bit contribution referenced from a 64 bit unit" );
1102
1114
1103
1115
uint64_t Size = DA.getU64 (&Offset);
1104
1116
uint8_t Version = DA.getU16 (&Offset);
@@ -1113,7 +1125,8 @@ parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
1113
1125
static Expected<StrOffsetsContributionDescriptor>
1114
1126
parseDWARF32StringOffsetsTableHeader (DWARFDataExtractor &DA, uint64_t Offset) {
1115
1127
if (!DA.isValidOffsetForDataOfSize (Offset, 8 ))
1116
- return createStringError (errc::invalid_argument, " section offset exceeds section size" );
1128
+ return createStringError (errc::invalid_argument,
1129
+ " section offset exceeds section size" );
1117
1130
1118
1131
uint32_t ContributionSize = DA.getU32 (&Offset);
1119
1132
if (ContributionSize >= dwarf::DW_LENGTH_lo_reserved)
@@ -1135,7 +1148,8 @@ parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA,
1135
1148
switch (Format) {
1136
1149
case dwarf::DwarfFormat::DWARF64: {
1137
1150
if (Offset < 16 )
1138
- return createStringError (errc::invalid_argument, " insufficient space for 64 bit header prefix" );
1151
+ return createStringError (errc::invalid_argument,
1152
+ " insufficient space for 64 bit header prefix" );
1139
1153
auto DescOrError = parseDWARF64StringOffsetsTableHeader (DA, Offset - 16 );
1140
1154
if (!DescOrError)
1141
1155
return DescOrError.takeError ();
@@ -1144,7 +1158,8 @@ parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA,
1144
1158
}
1145
1159
case dwarf::DwarfFormat::DWARF32: {
1146
1160
if (Offset < 8 )
1147
- return createStringError (errc::invalid_argument, " insufficient space for 32 bit header prefix" );
1161
+ return createStringError (errc::invalid_argument,
1162
+ " insufficient space for 32 bit header prefix" );
1148
1163
auto DescOrError = parseDWARF32StringOffsetsTableHeader (DA, Offset - 8 );
1149
1164
if (!DescOrError)
1150
1165
return DescOrError.takeError ();
@@ -1182,7 +1197,8 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA) {
1182
1197
return std::nullopt;
1183
1198
Offset += Header.getFormat () == dwarf::DwarfFormat::DWARF32 ? 8 : 16 ;
1184
1199
// Look for a valid contribution at the given offset.
1185
- auto DescOrError = parseDWARFStringOffsetsTableHeader (DA, Header.getFormat (), Offset);
1200
+ auto DescOrError =
1201
+ parseDWARFStringOffsetsTableHeader (DA, Header.getFormat (), Offset);
1186
1202
if (!DescOrError)
1187
1203
return DescOrError.takeError ();
1188
1204
return *DescOrError;
0 commit comments