Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -70,6 +70,9 @@ dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET; dw_offset_t m_file_offset; + std::mutex m_extractdies_mutex; + bool m_die_array_finished; + private: static uint8_t g_default_addr_size; Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -91,6 +91,8 @@ void DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) { if (m_data->m_die_array.size() > 1) { + std::lock_guard guard(m_data->m_extractdies_mutex); + // std::vectors never get any smaller when resized to a smaller size, // or when clear() or erase() are called, the size will report that it // is smaller, but the memory allocated remains intact (call capacity() @@ -118,9 +120,21 @@ // done. //---------------------------------------------------------------------- size_t DWARFCompileUnit::ExtractDIEsIfNeeded(bool cu_die_only) { - const size_t initial_die_array_size = m_data->m_die_array.size(); - if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1) - return 0; // Already parsed + size_t initial_die_array_size; + auto already_parsed = [cu_die_only, &initial_die_array_size]() -> bool { + return (cu_die_only && initial_die_array_size > 0) + || initial_die_array_size > 1; + }; + if (already_parsed() && m_data->m_die_array_finished) + return 0; + std::lock_guard guard(m_data->m_extractdies_mutex); + if (already_parsed()) { + lldbassert(m_data->m_die_array_finished); + return 0; + } + m_data->m_die_array_finished = false; + std::shared_ptr m_die_array_finished_set(nullptr, + [&](void*){ m_data->m_die_array_finished = true; }); static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(