diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index ae1f6fdb20a259..c62021b4bf6b0f 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -443,12 +443,11 @@ class ModuleList { static bool ModuleIsInCache(const Module *module_ptr); - static Status GetSharedModule(const ModuleSpec &module_spec, - lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, - bool *did_create_ptr, - bool always_create = false); + static Status + GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, + bool *did_create_ptr, bool always_create = false); static bool RemoveSharedModule(lldb::ModuleSP &module_sp); diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index 6234b8244b3f30..277fcf68cb0cb3 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -301,11 +301,10 @@ class Platform : public PluginInterface { LocateExecutableScriptingResources(Target *target, Module &module, Stream *feedback_stream); - virtual Status GetSharedModule(const ModuleSpec &module_spec, - Process *process, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, - bool *did_create_ptr); + virtual Status GetSharedModule( + const ModuleSpec &module_spec, Process *process, + lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); virtual bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec); diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 0345678ddafff4..76a861e33d0dc0 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -731,11 +731,11 @@ size_t ModuleList::RemoveOrphanSharedModules(bool mandatory) { return GetSharedModuleList().RemoveOrphans(mandatory); } -Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, - ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - ModuleSP *old_module_sp_ptr, - bool *did_create_ptr, bool always_create) { +Status +ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, + bool *did_create_ptr, bool always_create) { ModuleList &shared_module_list = GetSharedModuleList(); std::lock_guard guard( shared_module_list.m_modules_mutex); @@ -747,8 +747,6 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, if (did_create_ptr) *did_create_ptr = false; - if (old_module_sp_ptr) - old_module_sp_ptr->reset(); const UUID *uuid_ptr = module_spec.GetUUIDPtr(); const FileSpec &module_file_spec = module_spec.GetFileSpec(); @@ -769,8 +767,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, // Make sure the file for the module hasn't been modified if (module_sp->FileHasChanged()) { - if (old_module_sp_ptr && !*old_module_sp_ptr) - *old_module_sp_ptr = module_sp; + if (old_modules) + old_modules->push_back(module_sp); Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES)); if (log != nullptr) @@ -924,8 +922,8 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, located_binary_modulespec.GetFileSpec()); if (file_spec_mod_time != llvm::sys::TimePoint<>()) { if (file_spec_mod_time != module_sp->GetModificationTime()) { - if (old_module_sp_ptr) - *old_module_sp_ptr = module_sp; + if (old_modules) + old_modules->push_back(module_sp); shared_module_list.Remove(module_sp); module_sp.reset(); } diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index f5ec08a1a199cd..133eda93219c4b 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -221,7 +221,7 @@ BringInRemoteFile(Platform *platform, lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache( const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) { + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); LLDB_LOGF(log, @@ -238,7 +238,7 @@ lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache( Status err; err = ModuleList::GetSharedModule(module_spec, module_sp, - module_search_paths_ptr, old_module_sp_ptr, + module_search_paths_ptr, old_modules, did_create_ptr); if (module_sp) return err; @@ -341,8 +341,8 @@ lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache( Status PlatformDarwin::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Status error; module_sp.reset(); @@ -351,16 +351,16 @@ Status PlatformDarwin::GetSharedModule( // module first. if (m_remote_platform_sp) { error = m_remote_platform_sp->GetSharedModule( - module_spec, process, module_sp, module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); + module_spec, process, module_sp, module_search_paths_ptr, old_modules, + did_create_ptr); } } if (!module_sp) { // Fall back to the local platform and find the file locally error = Platform::GetSharedModule(module_spec, process, module_sp, - module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); + module_search_paths_ptr, old_modules, + did_create_ptr); const FileSpec &platform_file = module_spec.GetFileSpec(); if (!module_sp && module_search_paths_ptr && platform_file) { @@ -373,7 +373,7 @@ Status PlatformDarwin::GetSharedModule( new_module_spec.GetFileSpec() = bundle_directory; if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) { Status new_error(Platform::GetSharedModule( - new_module_spec, process, module_sp, nullptr, old_module_sp_ptr, + new_module_spec, process, module_sp, nullptr, old_modules, did_create_ptr)); if (module_sp) @@ -400,8 +400,8 @@ Status PlatformDarwin::GetSharedModule( ModuleSpec new_module_spec(module_spec); new_module_spec.GetFileSpec() = new_file_spec; Status new_error(Platform::GetSharedModule( - new_module_spec, process, module_sp, nullptr, - old_module_sp_ptr, did_create_ptr)); + new_module_spec, process, module_sp, nullptr, old_modules, + did_create_ptr)); if (module_sp) { module_sp->SetPlatformFileSpec(new_file_spec); @@ -1639,8 +1639,8 @@ PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) { lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { const FileSpec &platform_file = module_spec.GetFileSpec(); // See if the file is present in any of the module_search_paths_ptr // directories. @@ -1697,9 +1697,9 @@ lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( if (FileSystem::Instance().Exists(path_to_try)) { ModuleSpec new_module_spec(module_spec); new_module_spec.GetFileSpec() = path_to_try; - Status new_error(Platform::GetSharedModule( - new_module_spec, process, module_sp, nullptr, old_module_sp_ptr, - did_create_ptr)); + Status new_error( + Platform::GetSharedModule(new_module_spec, process, module_sp, + nullptr, old_modules, did_create_ptr)); if (module_sp) { module_sp->SetPlatformFileSpec(path_to_try); diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h index 8e28a70003106d..4e9a9495893b83 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -46,7 +46,7 @@ class PlatformDarwin : public PlatformPOSIX { GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; size_t GetSoftwareBreakpointTrapOpcode( @@ -132,7 +132,7 @@ class PlatformDarwin : public PlatformPOSIX { virtual lldb_private::Status GetSharedModuleWithLocalCache( const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr); + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); struct SDKEnumeratorInfo { lldb_private::FileSpec found_path; @@ -158,7 +158,7 @@ class PlatformDarwin : public PlatformPOSIX { const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr); + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr); static std::string FindComponentInPath(llvm::StringRef path, llvm::StringRef component); diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp index f6c0f262a37986..79cbc940feb57a 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp @@ -644,8 +644,8 @@ bool PlatformDarwinKernel::KernelHasdSYMSibling(const FileSpec &kernel_binary) { Status PlatformDarwinKernel::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { Status error; module_sp.reset(); const FileSpec &platform_file = module_spec.GetFileSpec(); @@ -676,7 +676,7 @@ Status PlatformDarwinKernel::GetSharedModule( // framework on macOS systems, a chance. error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp, module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); + old_modules, did_create_ptr); if (error.Success() && module_sp.get()) { return error; } diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h index 9cf9e41208eb80..203bfb5e6066c5 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h @@ -57,7 +57,7 @@ class PlatformDarwinKernel : public PlatformDarwin { GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; bool GetSupportedArchitectureAtIndex(uint32_t idx, diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp index 0b7f898ee0d338..cbdd2cde662b3f 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp @@ -292,10 +292,10 @@ lldb_private::Status PlatformMacOSX::GetSharedModule( const lldb_private::ModuleSpec &module_spec, Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) { - Status error = GetSharedModuleWithLocalCache( - module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr); + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { + Status error = GetSharedModuleWithLocalCache(module_spec, module_sp, + module_search_paths_ptr, + old_modules, did_create_ptr); if (module_sp) { if (module_spec.GetArchitecture().GetCore() == @@ -306,15 +306,16 @@ lldb_private::Status PlatformMacOSX::GetSharedModule( ModuleSpec module_spec_x86_64(module_spec); module_spec_x86_64.GetArchitecture() = ArchSpec("x86_64-apple-macosx"); lldb::ModuleSP x86_64_module_sp; - lldb::ModuleSP old_x86_64_module_sp; + llvm::SmallVector old_x86_64_modules; bool did_create = false; Status x86_64_error = GetSharedModuleWithLocalCache( module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr, - &old_x86_64_module_sp, &did_create); + &old_x86_64_modules, &did_create); if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) { module_sp = x86_64_module_sp; - if (old_module_sp_ptr) - *old_module_sp_ptr = old_x86_64_module_sp; + if (old_modules) + old_modules->append(old_x86_64_modules.begin(), + old_x86_64_modules.end()); if (did_create_ptr) *did_create_ptr = did_create; return x86_64_error; @@ -324,7 +325,9 @@ lldb_private::Status PlatformMacOSX::GetSharedModule( } if (!module_sp) { - error = FindBundleBinaryInExecSearchPaths (module_spec, process, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); + error = FindBundleBinaryInExecSearchPaths(module_spec, process, module_sp, + module_search_paths_ptr, + old_modules, did_create_ptr); } return error; } diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h index 30b11eb376849c..deca3f06ab7309 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h @@ -40,7 +40,7 @@ class PlatformMacOSX : public PlatformDarwin { GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; const char *GetDescription() override { diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp index e4ede0dc638b0b..065eefa48fea3c 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp @@ -504,8 +504,8 @@ Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file, Status PlatformRemoteDarwinDevice::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { // For iOS, the SDK files are all cached locally on the host system. So first // we ask for the file in the cached SDK, then we attempt to get a shared // module for the right architecture with the right UUID. @@ -608,24 +608,25 @@ Status PlatformRemoteDarwinDevice::GetSharedModule( // This may not be an SDK-related module. Try whether we can bring in the // thing to our local cache. error = GetSharedModuleWithLocalCache(module_spec, module_sp, - module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); + module_search_paths_ptr, old_modules, + did_create_ptr); if (error.Success()) return error; // See if the file is present in any of the module_search_paths_ptr // directories. if (!module_sp) - error = PlatformDarwin::FindBundleBinaryInExecSearchPaths (module_spec, process, module_sp, - module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); + error = PlatformDarwin::FindBundleBinaryInExecSearchPaths( + module_spec, process, module_sp, module_search_paths_ptr, old_modules, + did_create_ptr); if (error.Success()) return error; const bool always_create = false; - error = ModuleList::GetSharedModule( - module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr, always_create); + error = ModuleList::GetSharedModule(module_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr, always_create); if (module_sp) module_sp->SetPlatformFileSpec(platform_file); diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h index b1b760f16d457a..cc5f286f3b2597 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h @@ -38,7 +38,7 @@ class PlatformRemoteDarwinDevice : public PlatformDarwin { GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) override; void diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index 34ed7872c72065..e5afb4c7b8d759 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -218,15 +218,14 @@ Platform::LocateExecutableScriptingResources(Target *target, Module &module, // return PlatformSP(); //} -Status Platform::GetSharedModule(const ModuleSpec &module_spec, - Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { +Status Platform::GetSharedModule( + const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + llvm::SmallVectorImpl *old_modules, bool *did_create_ptr) { if (IsHost()) - return ModuleList::GetSharedModule( - module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr, false); + return ModuleList::GetSharedModule(module_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr, false); // Module resolver lambda. auto resolver = [&](const ModuleSpec &spec) { @@ -239,17 +238,17 @@ Status Platform::GetSharedModule(const ModuleSpec &module_spec, resolved_spec.GetFileSpec().PrependPathComponent( m_sdk_sysroot.GetStringRef()); // Try to get shared module with resolved spec. - error = ModuleList::GetSharedModule( - resolved_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr, false); + error = ModuleList::GetSharedModule(resolved_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr, false); } // If we don't have sysroot or it didn't work then // try original module spec. if (!error.Success()) { resolved_spec = spec; - error = ModuleList::GetSharedModule( - resolved_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, - did_create_ptr, false); + error = ModuleList::GetSharedModule(resolved_spec, module_sp, + module_search_paths_ptr, old_modules, + did_create_ptr, false); } if (error.Success() && module_sp) module_sp->SetPlatformFileSpec(resolved_spec.GetFileSpec()); diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 707344f99fcbad..19d0c3d477ebd0 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1965,8 +1965,9 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, module_sp = m_images.FindFirstModule(module_spec); if (!module_sp) { - ModuleSP old_module_sp; // This will get filled in if we have a new version - // of the library + llvm::SmallVector + old_modules; // This will get filled in if we have a new version + // of the library bool did_create_module = false; FileSpecList search_paths = GetExecutableSearchPaths(); // If there are image search path entries, try to use them first to acquire @@ -1979,7 +1980,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, transformed_spec.GetFileSpec().GetFilename() = module_spec.GetFileSpec().GetFilename(); error = ModuleList::GetSharedModule(transformed_spec, module_sp, - &search_paths, &old_module_sp, + &search_paths, &old_modules, &did_create_module); } } @@ -1997,7 +1998,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, // We have a UUID, it is OK to check the global module list... error = ModuleList::GetSharedModule(module_spec, module_sp, &search_paths, - &old_module_sp, &did_create_module); + &old_modules, &did_create_module); } if (!module_sp) { @@ -2006,7 +2007,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, if (m_platform_sp) { error = m_platform_sp->GetSharedModule( module_spec, m_process_sp.get(), module_sp, &search_paths, - &old_module_sp, &did_create_module); + &old_modules, &did_create_module); } else { error.SetErrorString("no platform is currently set"); } @@ -2057,18 +2058,18 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, // this target. So let's remove the UUID from the module list, and look // in the target's module list. Only do this if there is SOMETHING else // in the module spec... - if (!old_module_sp) { - if (module_spec.GetUUID().IsValid() && - !module_spec.GetFileSpec().GetFilename().IsEmpty() && - !module_spec.GetFileSpec().GetDirectory().IsEmpty()) { - ModuleSpec module_spec_copy(module_spec.GetFileSpec()); - module_spec_copy.GetUUID().Clear(); - - ModuleList found_modules; - m_images.FindModules(module_spec_copy, found_modules); - if (found_modules.GetSize() == 1) - old_module_sp = found_modules.GetModuleAtIndex(0); - } + if (module_spec.GetUUID().IsValid() && + !module_spec.GetFileSpec().GetFilename().IsEmpty() && + !module_spec.GetFileSpec().GetDirectory().IsEmpty()) { + ModuleSpec module_spec_copy(module_spec.GetFileSpec()); + module_spec_copy.GetUUID().Clear(); + + ModuleList found_modules; + m_images.FindModules(module_spec_copy, found_modules); + found_modules.ForEach([&](const ModuleSP &found_module) -> bool { + old_modules.push_back(found_module); + return true; + }); } // Preload symbols outside of any lock, so hopefully we can do this for @@ -2076,14 +2077,67 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, if (GetPreloadSymbols()) module_sp->PreloadSymbols(); - if (old_module_sp && m_images.GetIndexForModule(old_module_sp.get()) != - LLDB_INVALID_INDEX32) { - m_images.ReplaceModule(old_module_sp, module_sp); + llvm::SmallVector replaced_modules; + for (ModuleSP &old_module_sp : old_modules) { + if (m_images.GetIndexForModule(old_module_sp.get()) != + LLDB_INVALID_INDEX32) { + if (replaced_modules.empty()) + m_images.ReplaceModule(old_module_sp, module_sp); + else + m_images.Remove(old_module_sp); + + replaced_modules.push_back(std::move(old_module_sp)); + } + } + + if (replaced_modules.size() > 1) { + // The same new module replaced multiple old modules + // simultaneously. It's not clear this should ever + // happen (if we always replace old modules as we add + // new ones, presumably we should never have more than + // one old one). If there are legitimate cases where + // this happens, then the ModuleList::Notifier interface + // may need to be adjusted to allow reporting this. + // In the meantime, just log that this has happened; just + // above we called ReplaceModule on the first one, and Remove + // on the rest. + if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET | + LIBLLDB_LOG_MODULES)) { + StreamString message; + auto dump = [&message](Module &dump_module) -> void { + UUID dump_uuid = dump_module.GetUUID(); + + message << '['; + dump_module.GetDescription(message.AsRawOstream()); + message << " (uuid "; + + if (dump_uuid.IsValid()) + dump_uuid.Dump(&message); + else + message << "not specified"; + + message << ")]"; + }; + + message << "New module "; + dump(*module_sp); + message.AsRawOstream() + << llvm::formatv(" simultaneously replaced {0} old modules: ", + replaced_modules.size()); + for (ModuleSP &replaced_module_sp : replaced_modules) + dump(*replaced_module_sp); + + log->PutString(message.GetString()); + } + } + + if (replaced_modules.empty()) + m_images.Append(module_sp, notify); + + for (ModuleSP &old_module_sp : replaced_modules) { Module *old_module_ptr = old_module_sp.get(); old_module_sp.reset(); ModuleList::RemoveSharedModuleIfOrphaned(old_module_ptr); - } else { - m_images.Append(module_sp, notify); } } else module_sp.reset();