diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -443,12 +443,11 @@ 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 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -301,11 +301,10 @@ 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 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -741,11 +741,11 @@ 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); @@ -757,8 +757,6 @@ 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(); @@ -779,8 +777,8 @@ // 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) @@ -934,8 +932,8 @@ 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/PlatformAppleSimulator.h b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h --- a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h @@ -75,7 +75,7 @@ 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; uint32_t diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp --- a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp @@ -460,8 +460,8 @@ Status PlatformAppleSimulator::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/tvOS/watchOS, 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 @@ -476,9 +476,9 @@ module_search_paths_ptr); } else { 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/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -47,7 +47,7 @@ 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( @@ -138,7 +138,7 @@ 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; @@ -164,7 +164,7 @@ 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/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -221,7 +221,7 @@ 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, @@ -254,15 +254,15 @@ ModuleSpec shared_cache_spec(module_spec.GetFileSpec(), image_info.uuid, image_info.data_sp); err = ModuleList::GetSharedModule(shared_cache_spec, module_sp, - module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); + module_search_paths_ptr, old_modules, + did_create_ptr); if (module_sp) return 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; @@ -365,8 +365,8 @@ 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(); @@ -375,16 +375,16 @@ // 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) { @@ -397,7 +397,7 @@ 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) @@ -424,8 +424,8 @@ 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); @@ -1727,8 +1727,8 @@ 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. @@ -1785,9 +1785,9 @@ 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/PlatformDarwinKernel.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h @@ -57,7 +57,7 @@ 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, @@ -143,13 +143,14 @@ GetSharedModuleKext(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); lldb_private::Status GetSharedModuleKernel( 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); lldb_private::Status ExamineKextForMatchingUUID(const lldb_private::FileSpec &kext_bundle_path, diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp @@ -727,8 +727,8 @@ 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(); @@ -740,26 +740,26 @@ if (!kext_bundle_id.empty() && module_spec.GetUUID().IsValid()) { if (kext_bundle_id == "mach_kernel") { return GetSharedModuleKernel(module_spec, process, module_sp, - module_search_paths_ptr, old_module_sp_ptr, + module_search_paths_ptr, old_modules, did_create_ptr); } else { return GetSharedModuleKext(module_spec, process, module_sp, - module_search_paths_ptr, old_module_sp_ptr, + module_search_paths_ptr, old_modules, did_create_ptr); } } else { // Give the generic methods, including possibly calling into DebugSymbols // framework on macOS systems, a chance. return PlatformDarwin::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); } } Status PlatformDarwinKernel::GetSharedModuleKext( 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(); @@ -785,8 +785,8 @@ // Give the generic methods, including possibly calling into DebugSymbols // 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); + module_search_paths_ptr, old_modules, + did_create_ptr); if (error.Success() && module_sp.get()) { return error; } @@ -811,8 +811,8 @@ Status PlatformDarwinKernel::GetSharedModuleKernel( 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(); @@ -878,8 +878,8 @@ // Give the generic methods, including possibly calling into DebugSymbols // 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); + module_search_paths_ptr, old_modules, + did_create_ptr); if (error.Success() && module_sp.get()) { return error; } diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h --- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h @@ -38,7 +38,7 @@ 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/PlatformMacOSX.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp --- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp @@ -306,10 +306,10 @@ 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() == @@ -320,15 +320,16 @@ 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; @@ -338,7 +339,9 @@ } 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/PlatformRemoteDarwinDevice.h b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h --- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h @@ -38,7 +38,7 @@ 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/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp --- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp @@ -504,8 +504,8 @@ 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 @@ // 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/Target/Platform.cpp b/lldb/source/Target/Platform.cpp --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -218,15 +218,14 @@ // 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 @@ 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 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1973,8 +1973,9 @@ 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 @@ -1987,7 +1988,7 @@ 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); } } @@ -2005,7 +2006,7 @@ // 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) { @@ -2014,7 +2015,7 @@ 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"); } @@ -2065,18 +2066,18 @@ // 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 @@ -2084,15 +2085,65 @@ 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); - Module *old_module_ptr = old_module_sp.get(); - old_module_sp.reset(); - ModuleList::RemoveSharedModuleIfOrphaned(old_module_ptr); - } else { - m_images.Append(module_sp, notify); + if (old_modules.size() > 1) { + // The same new module replaces 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 is happening, + // call ReplaceModule on the first one, and RemoveModule + // 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 replacing {0} old modules: ", + old_modules.size()); + for (ModuleSP &old_module : old_modules) + dump(*old_module); + + log->PutString(message.GetString()); + } } + bool did_replace = false; + for (ModuleSP &old_module_sp : old_modules) { + if (m_images.GetIndexForModule(old_module_sp.get()) != + LLDB_INVALID_INDEX32) { + if (!did_replace) { + m_images.ReplaceModule(old_module_sp, module_sp); + did_replace = true; + } else + m_images.Remove(old_module_sp); + + Module *old_module_ptr = old_module_sp.get(); + old_module_sp.reset(); + ModuleList::RemoveSharedModuleIfOrphaned(old_module_ptr); + } + } + + if (!did_replace) + m_images.Append(module_sp, notify); } else module_sp.reset(); }