Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -75,6 +75,10 @@ std::unique_ptr m_cu_aranges_ap; // A quick address to compile unit table + // Protect m_compile_units. + // C++14: mutable std::shared_timed_mutex m_dwz_uniq_mutex; + mutable std::recursive_mutex m_dwz_uniq_mutex; + private: // All parsing needs to be done partially any managed by this class as // accessors are called. Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -39,6 +39,8 @@ // SetDwarfData //---------------------------------------------------------------------- void DWARFDebugInfo::SetDwarfData(SymbolFileDWARF *dwarf2Data) { + // C++14: std::lock_guard guard(m_dwz_uniq_mutex); + std::lock_guard guard(m_dwz_uniq_mutex); m_dwarf2Data = dwarf2Data; m_compile_units.clear(); } @@ -94,36 +96,51 @@ } void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() { - if (m_compile_units.empty()) { - if (m_dwarf2Data != NULL) { - lldb::offset_t file_offset = 0; - for (;;) { - DWARFCompileUnitSP cu_sp = - DWARFCompileUnit::Extract(m_dwarf2Data, &file_offset); - if (cu_sp.get() == NULL) - break; - - m_compile_units.push_back(cu_sp); - - file_offset = cu_sp->GetNextCompileUnitFileOffset(); - } + { + // C++14: std::shared_lock guard(m_dwz_uniq_mutex); + std::lock_guard guard(m_dwz_uniq_mutex); + if (!m_compile_units.empty()) + return; + } + if (m_dwarf2Data == NULL) + return; + lldb::offset_t file_offset = 0; + for (;;) { + DWARFCompileUnitSP cu_sp = + DWARFCompileUnit::Extract(m_dwarf2Data, &file_offset); + if (cu_sp.get() == NULL) + break; + + { + // C++14: std::lock_guard + // guard(m_dwz_uniq_mutex); + std::lock_guard guard(m_dwz_uniq_mutex); + m_compile_units.push_back(cu_sp); } + + file_offset = cu_sp->GetNextCompileUnitFileOffset(); } } size_t DWARFDebugInfo::GetNumCompileUnits() { ParseCompileUnitHeadersIfNeeded(); + // C++14: std::shared_lock guard(m_dwz_uniq_mutex); + std::lock_guard guard(m_dwz_uniq_mutex); return m_compile_units.size(); } DWARFCompileUnit *DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) { DWARFCompileUnit *cu = NULL; + // C++14: std::shared_lock guard(m_dwz_uniq_mutex); + std::lock_guard guard(m_dwz_uniq_mutex); if (idx < GetNumCompileUnits()) cu = m_compile_units[idx].get(); return cu; } bool DWARFDebugInfo::ContainsCompileUnit(const DWARFCompileUnit *cu) const { + // C++14: std::shared_lock guard(m_dwz_uniq_mutex); + std::lock_guard guard(m_dwz_uniq_mutex); // Not a verify efficient function, but it is handy for use in assertions // to make sure that a compile unit comes from a debug information file. CompileUnitColl::const_iterator end_pos = m_compile_units.end(); @@ -143,6 +160,8 @@ DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset, uint32_t *idx_ptr) { + // C++14: std::shared_lock guard(m_dwz_uniq_mutex); + std::lock_guard guard(m_dwz_uniq_mutex); DWARFCompileUnitSP cu_sp; uint32_t cu_idx = DW_INVALID_INDEX; if (cu_offset != DW_INVALID_OFFSET) { @@ -185,6 +204,8 @@ DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) { ParseCompileUnitHeadersIfNeeded(); + // C++14: std::shared_lock guard(m_dwz_uniq_mutex); + std::lock_guard guard(m_dwz_uniq_mutex); DWARFCompileUnitSP cu_sp; // Watch out for single compile unit executable as they are pretty common @@ -494,6 +515,8 @@ CompileUnitColl::const_iterator pos; uint32_t curr_depth = 0; ParseCompileUnitHeadersIfNeeded(); + // C++14: std::shared_lock guard(m_dwz_uniq_mutex); + std::lock_guard guard(m_dwz_uniq_mutex); for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos) { DWARFCompileUnit *cu = pos->get(); DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo);