Index: include/lldb/Symbol/SymbolFile.h =================================================================== --- include/lldb/Symbol/SymbolFile.h +++ include/lldb/Symbol/SymbolFile.h @@ -203,6 +203,8 @@ virtual void Dump(Stream &s) {} protected: + void AssertModuleLock(); + ObjectFile *m_obj_file; // The object file that symbols can be extracted from. uint32_t m_abilities; bool m_calculated_abilities; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -262,6 +262,7 @@ } TypeList *SymbolFileDWARF::GetTypeList() { + AssertModuleLock(); SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) return debug_map_symfile->GetTypeList(); @@ -343,6 +344,7 @@ uint32_t type_mask, TypeList &type_list) { + AssertModuleLock(); TypeSet type_set; CompileUnit *comp_unit = NULL; @@ -854,6 +856,7 @@ } CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) { + AssertModuleLock(); CompUnitSP cu_sp; DWARFDebugInfo *info = DebugInfo(); if (info) { @@ -866,6 +869,7 @@ Function *SymbolFileDWARF::ParseCompileUnitFunction(const SymbolContext &sc, const DWARFDIE &die) { + AssertModuleLock(); if (die.IsValid()) { TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); @@ -889,6 +893,7 @@ } lldb::LanguageType SymbolFileDWARF::ParseCompileUnitLanguage(const SymbolContext &sc) { + AssertModuleLock(); assert(sc.comp_unit); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); if (dwarf_cu) @@ -898,6 +903,7 @@ } size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) { + AssertModuleLock(); assert(sc.comp_unit); size_t functions_added = 0; DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); @@ -920,6 +926,7 @@ bool SymbolFileDWARF::ParseCompileUnitSupportFiles( const SymbolContext &sc, FileSpecList &support_files) { + AssertModuleLock(); assert(sc.comp_unit); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); if (dwarf_cu) { @@ -945,6 +952,7 @@ bool SymbolFileDWARF::ParseCompileUnitIsOptimized( const lldb_private::SymbolContext &sc) { + AssertModuleLock(); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); if (dwarf_cu) return dwarf_cu->GetIsOptimized(); @@ -954,6 +962,7 @@ bool SymbolFileDWARF::ParseImportedModules( const lldb_private::SymbolContext &sc, std::vector &imported_modules) { + AssertModuleLock(); assert(sc.comp_unit); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); if (dwarf_cu) { @@ -1031,6 +1040,7 @@ } bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) { + AssertModuleLock(); assert(sc.comp_unit); if (sc.comp_unit->GetLineTable() != NULL) return true; @@ -1116,6 +1126,7 @@ } bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) { + AssertModuleLock(); assert(sc.comp_unit); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); @@ -1295,6 +1306,8 @@ } SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) { + std::lock_guard guard( + GetObjectFile()->GetModule()->GetMutex()); // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple @@ -1311,6 +1324,8 @@ DWARFDIE SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) { + std::lock_guard guard( + GetObjectFile()->GetModule()->GetMutex()); // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple @@ -1325,6 +1340,8 @@ } CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { + std::lock_guard guard( + GetObjectFile()->GetModule()->GetMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1336,6 +1353,8 @@ CompilerDeclContext SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) { + std::lock_guard guard( + GetObjectFile()->GetModule()->GetMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1347,6 +1366,8 @@ CompilerDeclContext SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { + std::lock_guard guard( + GetObjectFile()->GetModule()->GetMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1357,6 +1378,8 @@ } Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { + std::lock_guard guard( + GetObjectFile()->GetModule()->GetMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -3069,6 +3092,7 @@ } size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc) { + AssertModuleLock(); assert(sc.comp_unit && sc.function); size_t functions_added = 0; DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); @@ -3085,6 +3109,7 @@ } size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) { + AssertModuleLock(); // At least a compile unit must be valid assert(sc.comp_unit); size_t types_added = 0; @@ -3108,6 +3133,7 @@ } size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { + AssertModuleLock(); if (sc.comp_unit != NULL) { DWARFDebugInfo *info = DebugInfo(); if (info == NULL) Index: source/Symbol/SymbolFile.cpp =================================================================== --- source/Symbol/SymbolFile.cpp +++ source/Symbol/SymbolFile.cpp @@ -19,6 +19,8 @@ #include "lldb/Utility/StreamString.h" #include "lldb/lldb-private.h" +#include + using namespace lldb_private; void SymbolFile::PreloadSymbols() { @@ -150,3 +152,16 @@ types.Clear(); return 0; } + +void SymbolFile::AssertModuleLock() { + // We assert that we have to module lock by trying to acquire the lock from a + // different thread. Note that we must abort if the result is true to + // guarantee correctness. + assert(std::async( + std::launch::async, + [this] { + return this->GetObjectFile()->GetModule()->GetMutex().try_lock(); + }) + .get() == false && + "Module is not locked"); +}