Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -18,6 +18,7 @@ #include "SymbolFileDWARF.h" #include "lldb/Core/STLUtils.h" #include "lldb/lldb-private.h" +#include "llvm/Support/RWMutex.h" typedef std::multimap CStringToDIEMap; @@ -74,6 +75,9 @@ std::unique_ptr m_cu_aranges_ap; // A quick address to compile unit table + std::atomic_size_t m_compile_units_size_atomic { 0 }; + mutable llvm::sys::RWMutex m_compile_units_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 @@ -40,6 +40,8 @@ // SetDwarfData //---------------------------------------------------------------------- void DWARFDebugInfo::SetDwarfData(SymbolFileDWARF *dwarf2Data) { + llvm::sys::ScopedWriter lock(m_compile_units_mutex); + m_compile_units_size_atomic = 0; m_dwarf2Data = dwarf2Data; m_compile_units.clear(); } @@ -96,32 +98,39 @@ } void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() { - if (m_compile_units.empty()) { - if (m_dwarf2Data != NULL) { - lldb::offset_t file_offset = 0; - DWARFUnitSP cu_sp; - while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, &file_offset))) { - m_compile_units.push_back(cu_sp); - - file_offset = cu_sp->GetNextCompileUnitFileOffset(); - } - } + if (m_compile_units_size_atomic) + return; + if (m_dwarf2Data == NULL) + return; + llvm::sys::ScopedWriter lock(m_compile_units_mutex); + if (!m_compile_units.empty()) + return; + lldb::offset_t file_offset = 0; + DWARFUnitSP cu_sp; + while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, &file_offset))) { + m_compile_units.push_back(cu_sp); + + file_offset = cu_sp->GetNextCompileUnitFileOffset(); } + m_compile_units_size_atomic = m_compile_units.size(); } size_t DWARFDebugInfo::GetNumCompileUnits() { ParseCompileUnitHeadersIfNeeded(); - return m_compile_units.size(); + return m_compile_units_size_atomic; } DWARFUnit *DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) { DWARFUnit *cu = NULL; - if (idx < GetNumCompileUnits()) + if (idx < GetNumCompileUnits()) { + llvm::sys::ScopedReader lock(m_compile_units_mutex); cu = m_compile_units[idx].get(); + } return cu; } bool DWARFDebugInfo::ContainsCompileUnit(const DWARFUnit *cu) const { + llvm::sys::ScopedReader lock(m_compile_units_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(); @@ -145,6 +154,7 @@ uint32_t cu_idx = DW_INVALID_INDEX; if (cu_offset != DW_INVALID_OFFSET) { ParseCompileUnitHeadersIfNeeded(); + llvm::sys::ScopedReader lock(m_compile_units_mutex); // Watch out for single compile unit executable as they are pretty common const size_t num_cus = m_compile_units.size(); @@ -185,6 +195,7 @@ DWARFUnit * DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) { ParseCompileUnitHeadersIfNeeded(); + llvm::sys::ScopedReader lock(m_compile_units_mutex); DWARFUnitSP cu_sp; @@ -494,6 +505,7 @@ CompileUnitColl::const_iterator pos; uint32_t curr_depth = 0; ParseCompileUnitHeadersIfNeeded(); + llvm::sys::ScopedReader lock(m_compile_units_mutex); for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos) { DWARFUnit *cu = pos->get(); DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo);