diff options
author | Jim Ingham <jingham@apple.com> | 2012-05-30 02:19:25 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2012-05-30 02:19:25 +0000 |
commit | 3ee12ef26ed534af3d0c85f88df7b06db037bfe3 (patch) | |
tree | 9d46961f3981c27e927926a4ea7d5a2c2b0b6ba7 | |
parent | 13586ab6d8a1c9f373315a70c384f67089c2371e (diff) | |
download | bcm5719-llvm-3ee12ef26ed534af3d0c85f88df7b06db037bfe3.tar.gz bcm5719-llvm-3ee12ef26ed534af3d0c85f88df7b06db037bfe3.zip |
We were accessing the ModuleList in the target without locking it for tasks like
setting breakpoints. That's dangerous, since while we are setting a breakpoint,
the target might hit the dyld load notification, and start removing modules from
the list. This change adds a GetMutex accessor to the ModuleList class, and
uses it whenever we are accessing the target's ModuleList (as returned by GetImages().)
<rdar://problem/11552372>
llvm-svn: 157668
12 files changed, 152 insertions, 54 deletions
diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index c3b9a637bc0..e1551f94c50 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -116,6 +116,13 @@ public: LogUUIDAndPaths (lldb::LogSP &log_sp, const char *prefix_cstr); + + Mutex & + GetMutex () + { + return m_modules_mutex; + } + uint32_t GetIndexForModule (const Module *module) const; @@ -135,6 +142,23 @@ public: GetModuleAtIndex (uint32_t idx); //------------------------------------------------------------------ + /// Get the module shared pointer for the module at index \a idx without + /// acquiring the ModuleList mutex. This MUST already have been + /// acquired with ModuleList::GetMutex and locked for this call to be safe. + /// + /// @param[in] idx + /// An index into this module collection. + /// + /// @return + /// A shared pointer to a Module which can contain NULL if + /// \a idx is out of range. + /// + /// @see ModuleList::GetSize() + //------------------------------------------------------------------ + lldb::ModuleSP + GetModuleAtIndexUnlocked (uint32_t idx); + + //------------------------------------------------------------------ /// Get the module pointer for the module at index \a idx. /// /// @param[in] idx @@ -150,6 +174,23 @@ public: GetModulePointerAtIndex (uint32_t idx) const; //------------------------------------------------------------------ + /// Get the module pointer for the module at index \a idx without + /// acquiring the ModuleList mutex. This MUST already have been + /// acquired with ModuleList::GetMutex and locked for this call to be safe. + /// + /// @param[in] idx + /// An index into this module collection. + /// + /// @return + /// A pointer to a Module which can by NULL if \a idx is out + /// of range. + /// + /// @see ModuleList::GetSize() + //------------------------------------------------------------------ + Module* + GetModulePointerAtIndexUnlocked (uint32_t idx) const; + + //------------------------------------------------------------------ /// Find compile units by partial or full path. /// /// Finds all compile units that match \a path in all of the modules diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp index 5d0cbd47e20..789118b3a40 100644 --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -317,6 +317,7 @@ Breakpoint::ClearAllBreakpointSites () void Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations) { + Mutex::Locker modules_mutex(module_list.GetMutex()); if (load) { // The logic for handling new modules is: @@ -332,11 +333,11 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_loca // resolving breakpoints will add new locations potentially. const size_t num_locs = m_locations.GetSize(); - - for (size_t i = 0; i < module_list.GetSize(); i++) + size_t num_modules = module_list.GetSize(); + for (size_t i = 0; i < num_modules; i++) { bool seen = false; - ModuleSP module_sp (module_list.GetModuleAtIndex (i)); + ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i)); if (!m_filter_sp->ModulePasses (module_sp)) continue; @@ -403,10 +404,11 @@ Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_loca shared_from_this()); else removed_locations_event = NULL; - - for (size_t i = 0; i < module_list.GetSize(); i++) + + size_t num_modules = module_list.GetSize(); + for (size_t i = 0; i < num_modules; i++) { - ModuleSP module_sp (module_list.GetModuleAtIndex (i)); + ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i)); if (m_filter_sp->ModulePasses (module_sp)) { size_t loc_idx = 0; diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index a38f143eb22..c5987eef539 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -1882,6 +1882,7 @@ public: if (command.GetArgumentCount() == 0) { // Dump all sections for all modules images + Mutex::Locker modules_locker(target->GetImages().GetMutex()); const uint32_t num_modules = target->GetImages().GetSize(); if (num_modules > 0) { @@ -1894,7 +1895,10 @@ public: result.GetOutputStream().EOL(); } num_dumped++; - DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order); + DumpModuleSymtab (m_interpreter, + result.GetOutputStream(), + target->GetImages().GetModulePointerAtIndexUnlocked(image_idx), + m_options.m_sort_order); } } else @@ -2179,13 +2183,15 @@ public: if (command.GetArgumentCount() == 0) { // Dump all sections for all modules images - const uint32_t num_modules = target->GetImages().GetSize(); + ModuleList &target_modules = target->GetImages(); + Mutex::Locker modules_locker (target_modules.GetMutex()); + const uint32_t num_modules = target_modules.GetSize(); if (num_modules > 0) { result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules); for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) { - if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx))) + if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx))) num_dumped++; } } @@ -2288,7 +2294,10 @@ public: for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) { FileSpec file_spec(arg_cstr, false); - const uint32_t num_modules = target->GetImages().GetSize(); + + ModuleList &target_modules = target->GetImages(); + Mutex::Locker modules_locker(target_modules.GetMutex()); + const uint32_t num_modules = target_modules.GetSize(); if (num_modules > 0) { uint32_t num_dumped = 0; @@ -2296,7 +2305,7 @@ public: { if (DumpCompileUnitLineTable (m_interpreter, result.GetOutputStream(), - target->GetImages().GetModulePointerAtIndex(i), + target_modules.GetModulePointerAtIndexUnlocked(i), file_spec, exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive())) num_dumped++; @@ -2807,9 +2816,6 @@ public: result.GetErrorStream().SetAddressByteSize(addr_byte_size); } // Dump all sections for all modules images - uint32_t num_modules = 0; - Mutex::Locker locker; - Stream &strm = result.GetOutputStream(); if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) @@ -2845,6 +2851,11 @@ public: return result.Succeeded(); } + uint32_t num_modules = 0; + Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL. + // Otherwise it will lock the AllocationModuleCollectionMutex when accessing + // the global module list directly. + ModuleList module_list; ModuleList *module_list_ptr = NULL; const size_t argc = command.GetArgumentCount(); @@ -2858,7 +2869,6 @@ public: else { module_list_ptr = &target->GetImages(); - num_modules = target->GetImages().GetSize(); } } else @@ -2879,9 +2889,14 @@ public: } } - num_modules = module_list.GetSize(); module_list_ptr = &module_list; } + + if (module_list_ptr != NULL) + { + locker.Lock(module_list_ptr->GetMutex()); + num_modules = module_list_ptr->GetSize(); + } if (num_modules > 0) { @@ -2891,7 +2906,7 @@ public: Module *module; if (module_list_ptr) { - module_sp = module_list_ptr->GetModuleAtIndex(image_idx); + module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx); module = module_sp.get(); } else @@ -3414,12 +3429,14 @@ public: if (command.GetArgumentCount() == 0) { // Dump all sections for all modules images - const uint32_t num_modules = target->GetImages().GetSize(); + ModuleList &target_modules = target->GetImages(); + Mutex::Locker modules_locker(target_modules.GetMutex()); + const uint32_t num_modules = target_modules.GetSize(); if (num_modules > 0) { for (i = 0; i<num_modules && syntax_error == false; ++i) { - if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error)) + if (LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error)) { result.GetOutputStream().EOL(); num_successful_lookups++; diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 8f852d4d8d1..157dafa7a2c 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -201,6 +201,12 @@ Module* ModuleList::GetModulePointerAtIndex (uint32_t idx) const { Mutex::Locker locker(m_modules_mutex); + return GetModulePointerAtIndexUnlocked(idx); +} + +Module* +ModuleList::GetModulePointerAtIndexUnlocked (uint32_t idx) const +{ if (idx < m_modules.size()) return m_modules[idx].get(); return NULL; @@ -210,6 +216,12 @@ ModuleSP ModuleList::GetModuleAtIndex(uint32_t idx) { Mutex::Locker locker(m_modules_mutex); + return GetModuleAtIndexUnlocked(idx); +} + +ModuleSP +ModuleList::GetModuleAtIndexUnlocked(uint32_t idx) +{ ModuleSP module_sp; if (idx < m_modules.size()) module_sp = m_modules[idx]; diff --git a/lldb/source/Core/SearchFilter.cpp b/lldb/source/Core/SearchFilter.cpp index b52ffdd24b0..f00f222bc30 100644 --- a/lldb/source/Core/SearchFilter.cpp +++ b/lldb/source/Core/SearchFilter.cpp @@ -160,11 +160,12 @@ SearchFilter::SearchInModuleList (Searcher &searcher, ModuleList &modules) searcher.SearchCallback (*this, empty_sc, NULL, false); else { + Mutex::Locker modules_locker(modules.GetMutex()); const size_t numModules = modules.GetSize(); for (size_t i = 0; i < numModules; i++) { - ModuleSP module_sp(modules.GetModuleAtIndex(i)); + ModuleSP module_sp(modules.GetModuleAtIndexUnlocked(i)); if (ModulePasses(module_sp)) { if (DoModuleIteration(module_sp, searcher) == Searcher::eCallbackReturnStop) @@ -191,12 +192,15 @@ SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searche { if (!context.module_sp) { - size_t n_modules = m_target_sp->GetImages().GetSize(); + ModuleList &target_images = m_target_sp->GetImages(); + Mutex::Locker modules_locker(target_images.GetMutex()); + + size_t n_modules = target_images.GetSize(); for (size_t i = 0; i < n_modules; i++) { // If this is the last level supplied, then call the callback directly, // otherwise descend. - ModuleSP module_sp(m_target_sp->GetImages().GetModuleAtIndex(i)); + ModuleSP module_sp(target_images.GetModuleAtIndexUnlocked (i)); if (!ModulePasses (module_sp)) continue; @@ -427,11 +431,13 @@ SearchFilterByModule::Search (Searcher &searcher) // filespec that passes. Otherwise, we need to go through all modules and // find the ones that match the file name. - ModuleList matching_modules; - const size_t num_modules = m_target_sp->GetImages().GetSize (); + ModuleList &target_modules = m_target_sp->GetImages(); + Mutex::Locker modules_locker (target_modules.GetMutex()); + + const size_t num_modules = target_modules.GetSize (); for (size_t i = 0; i < num_modules; i++) { - Module* module = m_target_sp->GetImages().GetModulePointerAtIndex(i); + Module* module = target_modules.GetModulePointerAtIndexUnlocked(i); if (FileSpec::Compare (m_module_spec, module->GetFileSpec(), false) == 0) { SymbolContext matchingContext(m_target_sp, module->shared_from_this()); @@ -591,11 +597,13 @@ SearchFilterByModuleList::Search (Searcher &searcher) // filespec that passes. Otherwise, we need to go through all modules and // find the ones that match the file name. - ModuleList matching_modules; - const size_t num_modules = m_target_sp->GetImages().GetSize (); + ModuleList &target_modules = m_target_sp->GetImages(); + Mutex::Locker modules_locker (target_modules.GetMutex()); + + const size_t num_modules = target_modules.GetSize (); for (size_t i = 0; i < num_modules; i++) { - Module* module = m_target_sp->GetImages().GetModulePointerAtIndex(i); + Module* module = target_modules.GetModulePointerAtIndexUnlocked(i); if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) != UINT32_MAX) { SymbolContext matchingContext(m_target_sp, module->shared_from_this()); @@ -762,11 +770,14 @@ SearchFilterByModuleListAndCU::Search (Searcher &searcher) // find the ones that match the file name. ModuleList matching_modules; - const size_t num_modules = m_target_sp->GetImages().GetSize (); + ModuleList &target_images = m_target_sp->GetImages(); + Mutex::Locker modules_locker(target_images.GetMutex()); + + const size_t num_modules = target_images.GetSize (); bool no_modules_in_filter = m_module_spec_list.GetSize() == 0; for (size_t i = 0; i < num_modules; i++) { - lldb::ModuleSP module_sp = m_target_sp->GetImages().GetModuleAtIndex(i); + lldb::ModuleSP module_sp = target_images.GetModuleAtIndexUnlocked(i); if (no_modules_in_filter || m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX) { SymbolContext matchingContext(m_target_sp, module_sp); diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index 4c31c223b89..605747adb56 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -561,13 +561,14 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, } else { - ModuleList &images = m_target->GetImages(); + ModuleList &target_images = m_target->GetImages(); + Mutex::Locker modules_locker (target_images.GetMutex()); - for (uint32_t i = 0, e = images.GetSize(); + for (uint32_t i = 0, e = target_images.GetSize(); i != e; ++i) { - lldb::ModuleSP image = images.GetModuleAtIndex(i); + lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i); if (!image) continue; @@ -1339,14 +1340,16 @@ ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespac } else { - ModuleList &images = m_target->GetImages(); + ModuleList &target_images = m_target->GetImages(); + Mutex::Locker modules_locker(target_images.GetMutex()); + ClangNamespaceDecl null_namespace_decl; - for (uint32_t i = 0, e = images.GetSize(); + for (uint32_t i = 0, e = target_images.GetSize(); i != e; ++i) { - lldb::ModuleSP image = images.GetModuleAtIndex(i); + lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i); if (!image) continue; diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index c8e9cec70c5..c42f469fea6 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -1057,12 +1057,14 @@ DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos () // to an equivalent version. We don't want it to stay in the target's module list or it will confuse // us, so unload it here. Target &target = m_process->GetTarget(); - ModuleList &modules = target.GetImages(); + ModuleList &target_modules = target.GetImages(); ModuleList not_loaded_modules; - size_t num_modules = modules.GetSize(); + Mutex::Locker modules_locker(target_modules.GetMutex()); + + size_t num_modules = target_modules.GetSize(); for (size_t i = 0; i < num_modules; i++) { - ModuleSP module_sp = modules.GetModuleAtIndex(i); + ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked (i); if (!module_sp->IsLoadedInTarget (&target)) { if (log) diff --git a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp index a1d64422e60..abfbf1c9ab6 100644 --- a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp +++ b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp @@ -97,10 +97,12 @@ DynamicLoaderStatic::LoadAllImagesAtFileAddresses () ModuleList loaded_module_list; + Mutex::Locker mutex_locker(module_list.GetMutex()); + const size_t num_modules = module_list.GetSize(); for (uint32_t idx = 0; idx < num_modules; ++idx) { - ModuleSP module_sp (module_list.GetModuleAtIndex (idx)); + ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (idx)); if (module_sp) { bool changed = false; diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index 1cb7ab8eef9..a2bc88872c1 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -263,11 +263,13 @@ AppleObjCRuntime::GetObjCVersion (Process *process, ModuleSP &objc_module_sp) return eObjC_VersionUnknown; Target &target = process->GetTarget(); - ModuleList &images = target.GetImages(); - size_t num_images = images.GetSize(); + ModuleList &target_modules = target.GetImages(); + Mutex::Locker modules_locker(target_modules.GetMutex()); + + size_t num_images = target_modules.GetSize(); for (size_t i = 0; i < num_images; i++) { - ModuleSP module_sp = images.GetModuleAtIndex(i); + ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i); // One tricky bit here is that we might get called as part of the initial module loading, but // before all the pre-run libraries get winnowed from the module list. So there might actually // be an old and incorrect ObjC library sitting around in the list, and we don't want to look at that. diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp index ff135806f28..00c90c6eacd 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp @@ -43,13 +43,14 @@ AppleObjCSymbolVendor::FindTypes (const SymbolContext& sc, uint32_t ret = 0; - ModuleList &images = m_process->GetTarget().GetImages(); + ModuleList &target_modules = m_process->GetTarget().GetImages(); + Mutex::Locker modules_locker(target_modules.GetMutex()); - for (size_t image_index = 0, end_index = images.GetSize(); + for (size_t image_index = 0, end_index = target_modules.GetSize(); image_index < end_index; ++image_index) { - Module *image = images.GetModulePointerAtIndex(image_index); + Module *image = target_modules.GetModulePointerAtIndexUnlocked(image_index); if (!image) continue; diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp index f8cab06732d..54eda8bddf5 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -334,15 +334,16 @@ AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols () return true; Target &target = m_process_sp->GetTarget(); - ModuleList &modules = target.GetImages(); - size_t num_modules = modules.GetSize(); + ModuleList &target_modules = target.GetImages(); + Mutex::Locker modules_locker(target_modules.GetMutex()); + size_t num_modules = target_modules.GetSize(); if (!m_objc_module_sp) { for (size_t i = 0; i < num_modules; i++) { - if (m_process_sp->GetObjCLanguageRuntime()->IsModuleObjCLibrary (modules.GetModuleAtIndex(i))) + if (m_process_sp->GetObjCLanguageRuntime()->IsModuleObjCLibrary (target_modules.GetModuleAtIndexUnlocked(i))) { - m_objc_module_sp = modules.GetModuleAtIndex(i); + m_objc_module_sp = target_modules.GetModuleAtIndexUnlocked(i); break; } } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 832feaac9ae..64626a97a7e 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -2814,19 +2814,23 @@ Process::CompleteAttach () m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL)); // Figure out which one is the executable, and set that in our target: - ModuleList &modules = m_target.GetImages(); + ModuleList &target_modules = m_target.GetImages(); + Mutex::Locker modules_locker(target_modules.GetMutex()); + size_t num_modules = target_modules.GetSize(); + ModuleSP new_executable_module_sp; - size_t num_modules = modules.GetSize(); for (int i = 0; i < num_modules; i++) { - ModuleSP module_sp (modules.GetModuleAtIndex(i)); + ModuleSP module_sp (target_modules.GetModuleAtIndexUnlocked (i)); if (module_sp && module_sp->IsExecutable()) { if (m_target.GetExecutableModulePointer() != module_sp.get()) - m_target.SetExecutableModule (module_sp, false); + new_executable_module_sp = module_sp; break; } } + if (new_executable_module_sp) + m_target.SetExecutableModule (new_executable_module_sp, false); } Error |