https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/180874
>From 8e20b05454a651d86e3a2d4197c0c520f0d413ee Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Tue, 10 Feb 2026 18:13:46 -0800 Subject: [PATCH 01/19] [lldb][macOS] Index shared cache files by UUID & filename The shared cache index only had accessors for getting a file from a shared cache by filename. In some environments like iOS Simulator, a filename can be either the actual realpath name of the framework in an SDK or simulator runtime install location, or rooted on / like /System/LibraryFrameworks/SwiftUI.framework. Because the searches for binaries were by filename, this divergence would be a problem. However, searching for binaries by the binary's UUID can remove taht ambiguity. I changed HostInfoMacOSX's store of SharedCacheImageInfo's to have a std::vector of all of the SharedCacheImageInfo's in a shared cache. Then I create a mapping of filename-to-SharedCacheImageInfo* and a mapping of UUID-to-SharedCacheImageInfo*, both pointing into the now-frozen std::vector. I added a HostInfo::GetSharedCacheImageInfo method to fetch an entry by shared-cache UUID + file UUID, in addition to the previous shared-cache UUID + filename. The filenames are stored as StringRefs in HostInfoMacOSX, but I was not convident about the lifetime of the c-strings I was getting from the libdyld SPI. I created ConstStrings for them and have the StringRef's refer to the constant string pool, to sidestep this problem. rdar://148939795 --- lldb/include/lldb/Host/HostInfoBase.h | 24 +++- .../include/lldb/Host/macosx/HostInfoMacOSX.h | 3 + .../Host/macosx/objcxx/HostInfoMacOSX.mm | 106 +++++++++++++++--- .../MacOSX-DYLD/DynamicLoaderDarwin.cpp | 25 +++-- .../Platform/MacOSX/PlatformDarwinDevice.cpp | 21 ++-- 5 files changed, 139 insertions(+), 40 deletions(-) diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index bc80e5e62ed39..d6423e602c7fc 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -30,15 +30,17 @@ class FileSpec; struct SharedCacheImageInfo { SharedCacheImageInfo() - : m_uuid(), m_extractor_sp(), m_create_data_extractor(nullptr), - m_image_baton(nullptr) {} - SharedCacheImageInfo(UUID uuid, lldb::DataExtractorSP extractor_sp) - : m_uuid(uuid), m_extractor_sp(extractor_sp), + : m_filename(), m_uuid(), m_extractor_sp(), + m_create_data_extractor(nullptr), m_image_baton(nullptr) {} + SharedCacheImageInfo(ConstString filename, UUID uuid, + lldb::DataExtractorSP extractor_sp) + : m_filename(filename), m_uuid(uuid), m_extractor_sp(extractor_sp), m_create_data_extractor(nullptr), m_image_baton(nullptr) {} SharedCacheImageInfo( - UUID uuid, lldb::DataExtractorSP (*create_data_extractor)(void *image), + ConstString filename, UUID uuid, + lldb::DataExtractorSP (*create_data_extractor)(void *image), void *image_baton) - : m_uuid(uuid), m_extractor_sp(), + : m_filename(filename), m_uuid(uuid), m_extractor_sp(), m_create_data_extractor(create_data_extractor), m_image_baton(image_baton) {} @@ -47,6 +49,7 @@ struct SharedCacheImageInfo { m_extractor_sp = m_create_data_extractor(m_image_baton); return m_extractor_sp; } + lldb_private::ConstString GetFilename() const { return m_filename; } const UUID &GetUUID() const { return m_uuid; } void *GetImageBaton(); void SetExtractor(lldb::DataExtractorSP extractor_sp) { @@ -57,6 +60,7 @@ struct SharedCacheImageInfo { lldb::DataExtractorSP (*create_data_extractor)(void *image)); private: + lldb_private::ConstString m_filename; UUID m_uuid; lldb::DataExtractorSP m_extractor_sp; lldb::DataExtractorSP (*m_create_data_extractor)(void *image); @@ -198,6 +202,14 @@ class HostInfoBase { return {}; } + /// Return information about module with UUID \p file_uuid, if it is loaded in + /// the current process's address space using shared cache \p sc_uuid. + /// The shared cache must have been previously indexed. + static SharedCacheImageInfo GetSharedCacheImageInfo(const UUID &file_uuid, + const UUID &sc_uuid) { + return {}; + } + /// Scan the files in a shared cache, if the filepath and uuid match /// on the debug host. /// Returns false if the shared cache filepath did not exist, or uuid diff --git a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h index c58056cb492b7..d57e5e9dd4a0c 100644 --- a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h +++ b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h @@ -48,6 +48,9 @@ class HostInfoMacOSX : public HostInfoPosix { static SharedCacheImageInfo GetSharedCacheImageInfo(llvm::StringRef image_name, const UUID &uuid); + static SharedCacheImageInfo GetSharedCacheImageInfo(const UUID &file_uuid, + const UUID &sc_uuid); + static bool SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid); protected: diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index d37062b152a00..dfb61d151cbb7 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -12,6 +12,7 @@ #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/LLDBLog.h" @@ -19,6 +20,7 @@ #include "lldb/Utility/Timer.h" #include "lldb/Utility/VirtualDataExtractor.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" @@ -684,14 +686,29 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache, namespace { class SharedCacheInfo { public: - llvm::StringMap<SharedCacheImageInfo> &GetImages() { - return m_caches[m_host_uuid]; + llvm::StringMap<SharedCacheImageInfo *> &GetFilenameToImageInfoMap() { + return m_filename_map[m_host_uuid]; + } + llvm::DenseMap<UUID, SharedCacheImageInfo *> &GetUUIDToImageInfoMap() { + return m_uuid_map[m_host_uuid]; + } + + bool + GetFilenameToImageInfoMap(llvm::StringMap<SharedCacheImageInfo *> **images, + const UUID &sc_uuid) { + if (m_filename_map.contains(sc_uuid)) { + *images = &m_filename_map[sc_uuid]; + return true; + } + *images = nullptr; + return false; } - bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images, - const UUID &uuid) { - if (m_caches.find(uuid) != m_caches.end()) { - *images = &m_caches[uuid]; + bool + GetUUIDToImageInfoMap(llvm::DenseMap<UUID, SharedCacheImageInfo *> **images, + const UUID &sc_uuid) { + if (m_uuid_map.contains(sc_uuid)) { + *images = &m_uuid_map[sc_uuid]; return true; } *images = nullptr; @@ -709,7 +726,12 @@ bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images, void CreateSharedCacheInfoLLDBsVirtualMemory(); bool CreateHostSharedCacheImageList(); - std::map<UUID, llvm::StringMap<SharedCacheImageInfo>> m_caches; + std::vector<SharedCacheImageInfo> m_file_infos; + llvm::SmallDenseMap<UUID, llvm::StringMap<SharedCacheImageInfo *>> + m_filename_map; + llvm::SmallDenseMap<UUID, llvm::DenseMap<UUID, SharedCacheImageInfo *>> + m_uuid_map; + UUID m_host_uuid; // macOS 26.4 and newer @@ -735,6 +757,9 @@ bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images, _dyld_get_shared_cache_uuid(dsc_uuid); m_host_uuid = UUID(dsc_uuid); + // In macOS 26, a shared cache has around 3500 files. + m_file_infos.reserve(4000); + if (ModuleList::GetGlobalModuleListProperties() .GetSharedCacheBinaryLoading() && CreateHostSharedCacheImageList()) @@ -866,20 +891,31 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( return; UUID image_uuid(uuid_tmp, sizeof(uuid_t)); + // Copy the filename into the const string pool to + // ensure lifetime. + ConstString installname(dyld_image_get_installname(image)); Log *log = GetLog(LLDBLog::Modules); if (log && log->GetVerbose()) - LLDB_LOGF(log, "sc file %s image %p", dyld_image_get_installname(image), + LLDB_LOGF(log, "sc file %s image %p", installname.GetCString(), (void *)image); m_dyld_image_retain_4HWTrace(image); - m_caches[m_host_uuid][dyld_image_get_installname(image)] = - SharedCacheImageInfo(image_uuid, map_shared_cache_binary_segments, - image); + m_file_infos.push_back(SharedCacheImageInfo( + installname, image_uuid, map_shared_cache_binary_segments, image)); }); }); if (return_failed) return false; + // vector of SharedCacheImageInfos has been fully populated, we can + // take pointers to the objects now. + size_t file_info_size = m_file_infos.size(); + for (size_t i = 0; i < file_info_size; i++) { + SharedCacheImageInfo *entry = &m_file_infos[i]; + m_filename_map[m_host_uuid][entry->GetFilename()] = entry; + m_uuid_map[m_host_uuid][entry->GetUUID()] = entry; + } + return true; } @@ -944,7 +980,10 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( lldb::DataBufferSP data_sp = std::make_shared<DataBufferUnowned>( (uint8_t *)minVmAddr, maxVmAddr - minVmAddr); lldb::DataExtractorSP extractor_sp = std::make_shared<DataExtractor>(data_sp); - m_caches[m_host_uuid][dyld_image_get_installname(image)] = + // Copy the filename into the const string pool to + // ensure lifetime. + ConstString installname(dyld_image_get_installname(image)); + m_caches[m_host_uuid][installname.GetStringRef()] = SharedCacheImageInfo{UUID(uuid, 16), extractor_sp}; }); return true; @@ -968,9 +1007,19 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( shared_cache_size - info->textSegmentOffset); lldb::DataExtractorSP extractor_sp = std::make_shared<DataExtractor>(buffer_sp); - m_caches[m_host_uuid][info->path] = - SharedCacheImageInfo{UUID(info->dylibUuid, 16), extractor_sp}; + ConstString filepath(info->path); + m_file_infos.push_back(SharedCacheImageInfo( + filepath, UUID(info->dylibUuid, 16), extractor_sp)); }); + + // vector of SharedCacheImageInfos has been fully populated, we can + // take pointers to the objects now. + size_t file_info_size = m_file_infos.size(); + for (size_t i = 0; i < file_info_size; i++) { + SharedCacheImageInfo *entry = &m_file_infos[i]; + m_filename_map[m_host_uuid][entry->GetFilename()] = entry; + m_uuid_map[m_host_uuid][entry->GetUUID()] = entry; + } } SharedCacheInfo &GetSharedCacheSingleton() { @@ -980,15 +1029,36 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( SharedCacheImageInfo HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name) { - return GetSharedCacheSingleton().GetImages().lookup(image_name); + SharedCacheImageInfo *entry = + GetSharedCacheSingleton().GetFilenameToImageInfoMap().lookup(image_name); + if (entry) + return *entry; + return {}; } SharedCacheImageInfo HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name, const UUID &uuid) { - llvm::StringMap<SharedCacheImageInfo> *shared_cache_info; - if (GetSharedCacheSingleton().GetImages(&shared_cache_info, uuid)) - return shared_cache_info->lookup(image_name); + llvm::StringMap<SharedCacheImageInfo *> *shared_cache_info; + if (GetSharedCacheSingleton().GetFilenameToImageInfoMap(&shared_cache_info, + uuid)) { + SharedCacheImageInfo *entry = shared_cache_info->lookup(image_name); + if (entry) + return *entry; + } + return {}; +} + +SharedCacheImageInfo +HostInfoMacOSX::GetSharedCacheImageInfo(const UUID &file_uuid, + const UUID &sc_uuid) { + llvm::DenseMap<UUID, SharedCacheImageInfo *> *shared_cache_info; + if (GetSharedCacheSingleton().GetUUIDToImageInfoMap(&shared_cache_info, + sc_uuid)) { + SharedCacheImageInfo *entry = shared_cache_info->lookup(file_uuid); + if (entry) + return *entry; + } return {}; } diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp index 0a8aa51a1469c..8658cba0689be 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -130,12 +130,13 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo( if (!module_sp && HostInfo::GetArchitecture().IsCompatibleMatch(target.GetArchitecture())) { - // When debugging on the host, we are most likely using the same shared - // cache as our inferior. The dylibs from the shared cache might not - // exist on the filesystem, so let's use the images in our own memory - // to create the modules. - // Check if the requested image is in our shared cache. + SharedCacheImageInfo image_info; + + // If we have a shared cache filepath and UUID, ask HostInfo + // if it can provide the SourceCacheImageInfo for the binary + // out of that shared cache. Search by the Module's UUID if + // available, else the filepath. addr_t sc_base_addr; UUID sc_uuid; LazyBool using_sc; @@ -143,12 +144,18 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo( FileSpec sc_path; if (GetSharedCacheInformation(sc_base_addr, sc_uuid, using_sc, private_sc, sc_path) && - sc_uuid) - image_info = HostInfo::GetSharedCacheImageInfo( - module_spec.GetFileSpec().GetPath(), sc_uuid); - else + sc_uuid) { + if (module_spec.GetUUID()) + image_info = + HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(), sc_uuid); + else + image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPath(), sc_uuid); + } else { + // Fall back to looking lldb's own shared cache by filename image_info = HostInfo::GetSharedCacheImageInfo( module_spec.GetFileSpec().GetPath()); + }; // If we found it and it has the correct UUID, let's proceed with // creating a module from the memory contents. diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp index 59d2f9ed9d856..ab12ada1fdf43 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp @@ -314,11 +314,11 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache( Status err; if (CheckLocalSharedCache()) { - // When debugging on the host, we are most likely using the same shared - // cache as our inferior. The dylibs from the shared cache might not - // exist on the filesystem, so let's use the images in our own memory - // to create the modules. + // If we have a shared cache filepath and UUID, ask HostInfo + // if it can provide the SourceCacheImageInfo for the binary + // out of that shared cache. Search by the Module's UUID if + // available, else the filepath. SharedCacheImageInfo image_info; if (process && process->GetDynamicLoader()) { addr_t sc_base_addr; @@ -326,11 +326,18 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache( LazyBool using_sc, private_sc; FileSpec sc_path; if (process->GetDynamicLoader()->GetSharedCacheInformation( - sc_base_addr, sc_uuid, using_sc, private_sc, sc_path)) - image_info = HostInfo::GetSharedCacheImageInfo( - module_spec.GetFileSpec().GetPath(), sc_uuid); + sc_base_addr, sc_uuid, using_sc, private_sc, sc_path)) { + if (module_spec.GetUUID()) { + image_info = + HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(), sc_uuid); + } else { + image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPath(), sc_uuid); + } + } } + // Fall back to looking for the file in lldb's own shared cache. if (!image_info.GetUUID()) image_info = HostInfo::GetSharedCacheImageInfo( module_spec.GetFileSpec().GetPath()); >From f313ebc8d290ef19038fe11e7d59f3c4c2607bb0 Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Wed, 11 Feb 2026 12:13:13 -0800 Subject: [PATCH 02/19] remove extra semicolon --- .../Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp index 8658cba0689be..19455838e988b 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -155,7 +155,7 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo( // Fall back to looking lldb's own shared cache by filename image_info = HostInfo::GetSharedCacheImageInfo( module_spec.GetFileSpec().GetPath()); - }; + } // If we found it and it has the correct UUID, let's proceed with // creating a module from the memory contents. >From 7536b6a10131034dbb232469d102dc147a2f15ad Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Thu, 12 Feb 2026 14:06:55 -0800 Subject: [PATCH 03/19] Update lldb/include/lldb/Host/HostInfoBase.h Co-authored-by: Jonas Devlieghere <[email protected]> --- lldb/include/lldb/Host/HostInfoBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index d6423e602c7fc..9110d38e9709f 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -60,7 +60,7 @@ struct SharedCacheImageInfo { lldb::DataExtractorSP (*create_data_extractor)(void *image)); private: - lldb_private::ConstString m_filename; + ConstString m_filename; UUID m_uuid; lldb::DataExtractorSP m_extractor_sp; lldb::DataExtractorSP (*m_create_data_extractor)(void *image); >From a24c8db9b0041a34a6979dbadaac4fcad2dac2ac Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 11:06:37 -0800 Subject: [PATCH 04/19] Update lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm Co-authored-by: Jonas Devlieghere <[email protected]> --- lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index dfb61d151cbb7..ba9e941013393 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -907,7 +907,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( if (return_failed) return false; - // vector of SharedCacheImageInfos has been fully populated, we can + // Vector of SharedCacheImageInfos has been fully populated, we can // take pointers to the objects now. size_t file_info_size = m_file_infos.size(); for (size_t i = 0; i < file_info_size; i++) { >From 8e76f92a055263e1b232c124ee7702c94088d535 Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 11:06:49 -0800 Subject: [PATCH 05/19] Update lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm Co-authored-by: Jonas Devlieghere <[email protected]> --- lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index ba9e941013393..21299a0c1d159 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -1029,9 +1029,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( SharedCacheImageInfo HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name) { - SharedCacheImageInfo *entry = - GetSharedCacheSingleton().GetFilenameToImageInfoMap().lookup(image_name); - if (entry) + if (SharedCacheImageInfo *entry = GetSharedCacheSingleton().GetFilenameToImageInfoMap().lookup(image_name)) return *entry; return {}; } >From 329a97c39abb040687e620ce69398976524d380f Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 11:07:22 -0800 Subject: [PATCH 06/19] Update lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm Co-authored-by: Jonas Devlieghere <[email protected]> --- lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index 21299a0c1d159..8e511dd864ea0 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -1040,8 +1040,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( llvm::StringMap<SharedCacheImageInfo *> *shared_cache_info; if (GetSharedCacheSingleton().GetFilenameToImageInfoMap(&shared_cache_info, uuid)) { - SharedCacheImageInfo *entry = shared_cache_info->lookup(image_name); - if (entry) + if (SharedCacheImageInfo *entry = shared_cache_info->lookup(image_name)) return *entry; } return {}; >From 4e2c9578667c0872db6e075af65a1e513e3573b3 Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 11:07:34 -0800 Subject: [PATCH 07/19] Update lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm Co-authored-by: Jonas Devlieghere <[email protected]> --- lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index 8e511dd864ea0..247e7dfd18078 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -1052,8 +1052,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( llvm::DenseMap<UUID, SharedCacheImageInfo *> *shared_cache_info; if (GetSharedCacheSingleton().GetUUIDToImageInfoMap(&shared_cache_info, sc_uuid)) { - SharedCacheImageInfo *entry = shared_cache_info->lookup(file_uuid); - if (entry) + if (SharedCacheImageInfo *entry = shared_cache_info->lookup(file_uuid)) return *entry; } return {}; >From c39e0a2a1fbcb9b64ff8522a3c5fc95b4f916b13 Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 13:40:45 -0800 Subject: [PATCH 08/19] Address Jonas' feedback points. Also, fix a mistake in HostInfoMacOSX where it would never use a shared cache other than lldb's own shared cache. Change the HostInfo::GetSharedCacheImageInfo calls to accept a ModuleSpec instead of having versions that take a filename or UUID. The HostInfoMacOSX method is a good place to check for either one based on which is available. --- lldb/include/lldb/Host/HostInfoBase.h | 15 +--- .../include/lldb/Host/macosx/HostInfoMacOSX.h | 8 +- .../Host/macosx/objcxx/HostInfoMacOSX.mm | 82 +++++++++---------- .../MacOSX-DYLD/DynamicLoaderDarwin.cpp | 10 +-- .../Platform/MacOSX/PlatformDarwinDevice.cpp | 11 +-- .../SymbolLocatorDebugSymbols.cpp | 8 +- .../ObjectFile/MachO/TestObjectFileMachO.cpp | 10 ++- 7 files changed, 60 insertions(+), 84 deletions(-) diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index 9110d38e9709f..0c6bf4c4b0983 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -187,25 +187,16 @@ class HostInfoBase { return llvm::errorCodeToError(llvm::errc::no_such_file_or_directory); } - /// Return information about module \p image_name if it is loaded in + /// Return information about module \p spec if it is loaded in /// the current process's address space. - static SharedCacheImageInfo - GetSharedCacheImageInfo(llvm::StringRef image_name) { - return {}; - } - - /// Return information about module \p image_name if it is loaded in - /// the current process's address space using shared cache \p uuid. - /// The shared cache UUID must have been previously indexed. - static SharedCacheImageInfo - GetSharedCacheImageInfo(llvm::StringRef image_name, const UUID &uuid) { + static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec) { return {}; } /// Return information about module with UUID \p file_uuid, if it is loaded in /// the current process's address space using shared cache \p sc_uuid. /// The shared cache must have been previously indexed. - static SharedCacheImageInfo GetSharedCacheImageInfo(const UUID &file_uuid, + static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec, const UUID &sc_uuid) { return {}; } diff --git a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h index d57e5e9dd4a0c..7ec8c8d852cf6 100644 --- a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h +++ b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h @@ -42,13 +42,9 @@ class HostInfoMacOSX : public HostInfoPosix { llvm::StringRef tool); /// Shared cache utilities - static SharedCacheImageInfo - GetSharedCacheImageInfo(llvm::StringRef image_name); + static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec); - static SharedCacheImageInfo - GetSharedCacheImageInfo(llvm::StringRef image_name, const UUID &uuid); - - static SharedCacheImageInfo GetSharedCacheImageInfo(const UUID &file_uuid, + static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec, const UUID &sc_uuid); static bool SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid); diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index 247e7dfd18078..05e094e60c440 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -686,33 +686,26 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache, namespace { class SharedCacheInfo { public: - llvm::StringMap<SharedCacheImageInfo *> &GetFilenameToImageInfoMap() { + llvm::DenseMap<ConstString, SharedCacheImageInfo *> & + GetHostSCFilenameToImageInfoMap() { return m_filename_map[m_host_uuid]; } - llvm::DenseMap<UUID, SharedCacheImageInfo *> &GetUUIDToImageInfoMap() { + llvm::DenseMap<UUID, SharedCacheImageInfo *> &GetHostSCUUIDToImageInfoMap() { return m_uuid_map[m_host_uuid]; } - bool - GetFilenameToImageInfoMap(llvm::StringMap<SharedCacheImageInfo *> **images, - const UUID &sc_uuid) { - if (m_filename_map.contains(sc_uuid)) { - *images = &m_filename_map[sc_uuid]; - return true; - } - *images = nullptr; - return false; + llvm::DenseMap<ConstString, SharedCacheImageInfo *> * + GetFilenameToImageInfoMap(const UUID &sc_uuid) { + if (m_filename_map.contains(sc_uuid)) + return &m_filename_map[sc_uuid]; + return nullptr; } - bool - GetUUIDToImageInfoMap(llvm::DenseMap<UUID, SharedCacheImageInfo *> **images, - const UUID &sc_uuid) { - if (m_uuid_map.contains(sc_uuid)) { - *images = &m_uuid_map[sc_uuid]; - return true; - } - *images = nullptr; - return false; + llvm::DenseMap<UUID, SharedCacheImageInfo *> * + GetUUIDToImageInfoMap(const UUID &sc_uuid) { + if (m_uuid_map.contains(sc_uuid)) + return &m_uuid_map[sc_uuid]; + return nullptr; } /// Given the UUID and filepath to a shared cache on the local debug host @@ -727,7 +720,7 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache, bool CreateHostSharedCacheImageList(); std::vector<SharedCacheImageInfo> m_file_infos; - llvm::SmallDenseMap<UUID, llvm::StringMap<SharedCacheImageInfo *>> + llvm::SmallDenseMap<UUID, llvm::DenseMap<ConstString, SharedCacheImageInfo *>> m_filename_map; llvm::SmallDenseMap<UUID, llvm::DenseMap<UUID, SharedCacheImageInfo *>> m_uuid_map; @@ -1012,7 +1005,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( filepath, UUID(info->dylibUuid, 16), extractor_sp)); }); - // vector of SharedCacheImageInfos has been fully populated, we can + // std::vector of SharedCacheImageInfos has been fully populated, we can // take pointers to the objects now. size_t file_info_size = m_file_infos.size(); for (size_t i = 0; i < file_info_size; i++) { @@ -1028,33 +1021,36 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( } SharedCacheImageInfo -HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name) { - if (SharedCacheImageInfo *entry = GetSharedCacheSingleton().GetFilenameToImageInfoMap().lookup(image_name)) +HostInfoMacOSX::GetSharedCacheImageInfo(const ModuleSpec &spec) { + SharedCacheImageInfo *entry = nullptr; + if (spec.GetUUID()) + entry = GetSharedCacheSingleton().GetHostSCUUIDToImageInfoMap().lookup( + spec.GetUUID()); + else + entry = GetSharedCacheSingleton().GetHostSCFilenameToImageInfoMap().lookup( + spec.GetFileSpec().GetPathAsConstString()); + if (entry) return *entry; return {}; } SharedCacheImageInfo -HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name, - const UUID &uuid) { - llvm::StringMap<SharedCacheImageInfo *> *shared_cache_info; - if (GetSharedCacheSingleton().GetFilenameToImageInfoMap(&shared_cache_info, - uuid)) { - if (SharedCacheImageInfo *entry = shared_cache_info->lookup(image_name)) - return *entry; - } - return {}; -} - -SharedCacheImageInfo -HostInfoMacOSX::GetSharedCacheImageInfo(const UUID &file_uuid, +HostInfoMacOSX::GetSharedCacheImageInfo(const ModuleSpec &spec, const UUID &sc_uuid) { - llvm::DenseMap<UUID, SharedCacheImageInfo *> *shared_cache_info; - if (GetSharedCacheSingleton().GetUUIDToImageInfoMap(&shared_cache_info, - sc_uuid)) { - if (SharedCacheImageInfo *entry = shared_cache_info->lookup(file_uuid)) - return *entry; - } + llvm::DenseMap<UUID, SharedCacheImageInfo *> *uuid_to_fileinfos = + GetSharedCacheSingleton().GetUUIDToImageInfoMap(sc_uuid); + llvm::DenseMap<ConstString, SharedCacheImageInfo *> *filename_to_fileinfos = + GetSharedCacheSingleton().GetFilenameToImageInfoMap(sc_uuid); + + SharedCacheImageInfo *entry = nullptr; + if (uuid_to_fileinfos && spec.GetUUID()) + entry = uuid_to_fileinfos->lookup(spec.GetUUID()); + else if (filename_to_fileinfos) + entry = filename_to_fileinfos->lookup( + spec.GetFileSpec().GetPathAsConstString()); + + if (entry) + return *entry; return {}; } diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp index 19455838e988b..f70a08de3c5ee 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -145,16 +145,10 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo( if (GetSharedCacheInformation(sc_base_addr, sc_uuid, using_sc, private_sc, sc_path) && sc_uuid) { - if (module_spec.GetUUID()) - image_info = - HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(), sc_uuid); - else - image_info = HostInfo::GetSharedCacheImageInfo( - module_spec.GetFileSpec().GetPath(), sc_uuid); + image_info = HostInfo::GetSharedCacheImageInfo(module_spec, sc_uuid); } else { // Fall back to looking lldb's own shared cache by filename - image_info = HostInfo::GetSharedCacheImageInfo( - module_spec.GetFileSpec().GetPath()); + image_info = HostInfo::GetSharedCacheImageInfo(module_spec); } // If we found it and it has the correct UUID, let's proceed with diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp index ab12ada1fdf43..890ad300b3e36 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp @@ -327,20 +327,13 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache( FileSpec sc_path; if (process->GetDynamicLoader()->GetSharedCacheInformation( sc_base_addr, sc_uuid, using_sc, private_sc, sc_path)) { - if (module_spec.GetUUID()) { - image_info = - HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(), sc_uuid); - } else { - image_info = HostInfo::GetSharedCacheImageInfo( - module_spec.GetFileSpec().GetPath(), sc_uuid); - } + image_info = HostInfo::GetSharedCacheImageInfo(module_spec, sc_uuid); } } // Fall back to looking for the file in lldb's own shared cache. if (!image_info.GetUUID()) - image_info = HostInfo::GetSharedCacheImageInfo( - module_spec.GetFileSpec().GetPath()); + image_info = HostInfo::GetSharedCacheImageInfo(module_spec); // If we found it and it has the correct UUID, let's proceed with // creating a module from the memory contents. diff --git a/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp index f4b572c9e88ac..8597dff457c39 100644 --- a/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp +++ b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp @@ -203,8 +203,8 @@ std::optional<ModuleSpec> SymbolLocatorDebugSymbols::LocateExecutableObjectFile( // Check if the requested image is in our shared cache. if (!success) { - SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( - module_spec.GetFileSpec().GetPath()); + SharedCacheImageInfo image_info = + HostInfo::GetSharedCacheImageInfo(module_spec); // If we found it and it has the correct UUID, let's proceed with // creating a module from the memory contents. @@ -646,8 +646,8 @@ static int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, // Check if the requested image is in our shared cache. if (!success) { - SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( - module_spec.GetFileSpec().GetPath()); + SharedCacheImageInfo image_info = + HostInfo::GetSharedCacheImageInfo(module_spec); // If we found it and it has the correct UUID, let's proceed with // creating a module from the memory contents. diff --git a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp index 5b516fc2582f5..a761b55983edf 100644 --- a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp +++ b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp @@ -12,8 +12,10 @@ #include "TestingSupport/SubsystemRAII.h" #include "TestingSupport/TestUtilities.h" #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Utility/FileSpec.h" #include "lldb/lldb-defines.h" #include "gtest/gtest.h" @@ -37,8 +39,10 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) { Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch)); + ModuleSpec mod_spec; + mod_spec.GetFileSpec() = FileSpec("/usr/lib/libobjc.A.dylib"); SharedCacheImageInfo image_info = - HostInfo::GetSharedCacheImageInfo("/usr/lib/libobjc.A.dylib"); + HostInfo::GetSharedCacheImageInfo(mod_spec); EXPECT_TRUE(image_info.GetUUID()); EXPECT_TRUE(image_info.GetExtractor()); @@ -85,8 +89,10 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) { } TEST_F(ObjectFileMachOTest, IndirectSymbolsInTheSharedCache) { + ModuleSpec mod_spec; + mod_spec.GetFileSpec() = FileSpec("/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit"); SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( - "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit"); + mod_spec); ModuleSpec spec(FileSpec(), UUID(), image_info.GetExtractor()); lldb::ModuleSP module = std::make_shared<Module>(spec); >From aa8c6e250f44b5e519432a9f430821b1d677709f Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 13:48:17 -0800 Subject: [PATCH 09/19] ws fix --- lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp index a761b55983edf..3b646f83ce1eb 100644 --- a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp +++ b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp @@ -41,8 +41,7 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) { ModuleSpec mod_spec; mod_spec.GetFileSpec() = FileSpec("/usr/lib/libobjc.A.dylib"); - SharedCacheImageInfo image_info = - HostInfo::GetSharedCacheImageInfo(mod_spec); + SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(mod_spec); EXPECT_TRUE(image_info.GetUUID()); EXPECT_TRUE(image_info.GetExtractor()); @@ -91,8 +90,7 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) { TEST_F(ObjectFileMachOTest, IndirectSymbolsInTheSharedCache) { ModuleSpec mod_spec; mod_spec.GetFileSpec() = FileSpec("/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit"); - SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( - mod_spec); + SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(mod_spec); ModuleSpec spec(FileSpec(), UUID(), image_info.GetExtractor()); lldb::ModuleSP module = std::make_shared<Module>(spec); >From a010907778f5b07307f001ca42f48af4dee3501c Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 15:28:43 -0800 Subject: [PATCH 10/19] ws fix --- lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp index 3b646f83ce1eb..8c7e0d6a4080c 100644 --- a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp +++ b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp @@ -89,7 +89,8 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) { TEST_F(ObjectFileMachOTest, IndirectSymbolsInTheSharedCache) { ModuleSpec mod_spec; - mod_spec.GetFileSpec() = FileSpec("/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit"); + mod_spec.GetFileSpec() = + FileSpec("/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit"); SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(mod_spec); ModuleSpec spec(FileSpec(), UUID(), image_info.GetExtractor()); lldb::ModuleSP module = std::make_shared<Module>(spec); >From ab1000f3889e4f63bb1b376dfd909345b07a001b Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 17:02:26 -0800 Subject: [PATCH 11/19] fixups after github merge. --- lldb/include/lldb/Host/HostInfoBase.h | 13 ++++++++----- lldb/include/lldb/Host/macosx/HostInfoMacOSX.h | 10 +++++----- .../MacOSX-DYLD/DynamicLoaderDarwin.cpp | 3 ++- .../Platform/MacOSX/PlatformDarwinDevice.cpp | 3 ++- .../ObjectFile/MachO/TestObjectFileMachO.cpp | 8 ++++---- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index c34791d8f2b68..8103f1c0a595a 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -194,8 +194,9 @@ class HostInfoBase { /// Flag to control if this method can try to read a shared /// cache binary blob directly, needed to keep user settings out of /// Host. - static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec, - lldb::SymbolSharedCacheUse sc_mode) { + static SharedCacheImageInfo + GetSharedCacheImageInfo(const ModuleSpec &spec, + lldb::SymbolSharedCacheUse sc_mode) { return {}; } @@ -207,9 +208,11 @@ class HostInfoBase { /// Flag to control if this method can try to read a shared /// cache binary blob directly, needed to keep user settings out of /// Host. - static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec, - const UUID &sc_uuid, - lldb::SymbolSharedCacheUse sc_mode) { + static SharedCacheImageInfo + GetSharedCacheImageInfo(const ModuleSpec &spec, const UUID &sc_uuid, + lldb::SymbolSharedCacheUse sc_mode) { + return {}; + } /// Return information about module \p image_name if it is loaded in /// the current process's address space using shared cache \p uuid. diff --git a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h index 3f27e0c6d1c25..d8ed6e6227686 100644 --- a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h +++ b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h @@ -42,12 +42,12 @@ class HostInfoMacOSX : public HostInfoPosix { llvm::StringRef tool); /// Shared cache utilities - static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec - lldb::SymbolSharedCacheUse sc_mode); + static SharedCacheImageInfo GetSharedCacheImageInfo( + const ModuleSpec &spec lldb::SymbolSharedCacheUse sc_mode); - static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec, - const UUID &sc_uuid, - lldb::SymbolSharedCacheUse sc_mode); + static SharedCacheImageInfo + GetSharedCacheImageInfo(const ModuleSpec &spec, const UUID &sc_uuid, + lldb::SymbolSharedCacheUse sc_mode); static bool SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid, lldb::SymbolSharedCacheUse sc_mode); diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp index 1adc648748f47..45059ace6b415 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -147,7 +147,8 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo( if (GetSharedCacheInformation(sc_base_addr, sc_uuid, using_sc, private_sc, sc_path) && sc_uuid) { - image_info = HostInfo::GetSharedCacheImageInfo(module_spec, sc_uuid, sc_mode); + image_info = + HostInfo::GetSharedCacheImageInfo(module_spec, sc_uuid, sc_mode); } else { // Fall back to looking lldb's own shared cache by filename image_info = HostInfo::GetSharedCacheImageInfo(module_spec, sc_mode); diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp index 3454dbff455ff..d1a1abca00091 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp @@ -325,7 +325,8 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache( FileSpec sc_path; if (process->GetDynamicLoader()->GetSharedCacheInformation( sc_base_addr, sc_uuid, using_sc, private_sc, sc_path)) { - image_info = HostInfo::GetSharedCacheImageInfo(module_spec, sc_uuid, sc_mode); + image_info = + HostInfo::GetSharedCacheImageInfo(module_spec, sc_uuid, sc_mode); } } diff --git a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp index 667b03c47999f..acedf9a3d19d3 100644 --- a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp +++ b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp @@ -41,8 +41,8 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) { ModuleSpec mod_spec; mod_spec.GetFileSpec() = FileSpec("/usr/lib/libobjc.A.dylib"); - SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(mod_spec, - lldb::eSymbolSharedCacheUseHostSharedCache); + SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( + mod_spec, lldb::eSymbolSharedCacheUseHostSharedCache); EXPECT_TRUE(image_info.GetUUID()); EXPECT_TRUE(image_info.GetExtractor()); @@ -92,8 +92,8 @@ TEST_F(ObjectFileMachOTest, IndirectSymbolsInTheSharedCache) { ModuleSpec mod_spec; mod_spec.GetFileSpec() = FileSpec("/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit"); - SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(mod_spec, - lldb::eSymbolSharedCacheUseHostSharedCache); + SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( + mod_spec, lldb::eSymbolSharedCacheUseHostSharedCache); ModuleSpec spec(FileSpec(), UUID(), image_info.GetExtractor()); lldb::ModuleSP module = std::make_shared<Module>(spec); >From ca15f4fdd15d62161dd32ef1b508447f1aef668b Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 17:09:43 -0800 Subject: [PATCH 12/19] fix merge typeo --- lldb/include/lldb/Host/macosx/HostInfoMacOSX.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h index d8ed6e6227686..69b1d80419ee3 100644 --- a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h +++ b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h @@ -43,7 +43,7 @@ class HostInfoMacOSX : public HostInfoPosix { /// Shared cache utilities static SharedCacheImageInfo GetSharedCacheImageInfo( - const ModuleSpec &spec lldb::SymbolSharedCacheUse sc_mode); + const ModuleSpec &spec, lldb::SymbolSharedCacheUse sc_mode); static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec, const UUID &sc_uuid, >From 09c66e15808647aba3daab29e4b1dc826043afd2 Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 17:47:20 -0800 Subject: [PATCH 13/19] Fixes after the tricky merge. Also stop using ModuleSpec in HostInfoMacOSX, go back to duplicating methods to take either a file UUID or a filepath. ModuleSpec is in Core, and Host can't use that. --- lldb/include/lldb/Host/HostInfoBase.h | 35 +++++++++++-- .../include/lldb/Host/macosx/HostInfoMacOSX.h | 12 +++-- .../Host/macosx/objcxx/HostInfoMacOSX.mm | 49 +++++++++++-------- .../MacOSX-DYLD/DynamicLoaderDarwin.cpp | 12 +++-- .../Platform/MacOSX/PlatformDarwinDevice.cpp | 12 +++-- .../SymbolLocatorDebugSymbols.cpp | 8 +-- .../ObjectFile/MachO/TestObjectFileMachO.cpp | 12 ++--- 7 files changed, 95 insertions(+), 45 deletions(-) diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index 8103f1c0a595a..e355a65520f23 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -187,7 +187,7 @@ class HostInfoBase { return llvm::errorCodeToError(llvm::errc::no_such_file_or_directory); } - /// Return information about module \p spec if it is loaded in + /// Return information about module \p filepath if it is loaded in /// the current process's address space. /// /// \param[in] sc_mode @@ -195,12 +195,39 @@ class HostInfoBase { /// cache binary blob directly, needed to keep user settings out of /// Host. static SharedCacheImageInfo - GetSharedCacheImageInfo(const ModuleSpec &spec, + GetSharedCacheImageInfo(ConstString filepath, lldb::SymbolSharedCacheUse sc_mode) { return {}; } - /// Return information about module \p spec, if it is loaded in + /// Return information about module \p uuid if it is loaded in + /// the current process's address space. + /// + /// \param[in] sc_mode + /// Flag to control if this method can try to read a shared + /// cache binary blob directly, needed to keep user settings out of + /// Host. + static SharedCacheImageInfo + GetSharedCacheImageInfo(const UUID &uuid, + lldb::SymbolSharedCacheUse sc_mode) { + return {}; + } + + /// Return information about module \p filepath, if it is loaded in + /// the current process's address space using shared cache \p sc_uuid. + /// The shared cache must have been previously indexed. + /// + /// \param[in] sc_mode + /// Flag to control if this method can try to read a shared + /// cache binary blob directly, needed to keep user settings out of + /// Host. + static SharedCacheImageInfo + GetSharedCacheImageInfo(ConstString filepath, const UUID &sc_uuid, + lldb::SymbolSharedCacheUse sc_mode) { + return {}; + } + + /// Return information about module \p uuid, if it is loaded in /// the current process's address space using shared cache \p sc_uuid. /// The shared cache must have been previously indexed. /// @@ -209,7 +236,7 @@ class HostInfoBase { /// cache binary blob directly, needed to keep user settings out of /// Host. static SharedCacheImageInfo - GetSharedCacheImageInfo(const ModuleSpec &spec, const UUID &sc_uuid, + GetSharedCacheImageInfo(const UUID &uuid, const UUID &sc_uuid, lldb::SymbolSharedCacheUse sc_mode) { return {}; } diff --git a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h index 69b1d80419ee3..ed00c44df4bdc 100644 --- a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h +++ b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h @@ -42,11 +42,17 @@ class HostInfoMacOSX : public HostInfoPosix { llvm::StringRef tool); /// Shared cache utilities - static SharedCacheImageInfo GetSharedCacheImageInfo( - const ModuleSpec &spec, lldb::SymbolSharedCacheUse sc_mode); + static SharedCacheImageInfo + GetSharedCacheImageInfo(ConstString filepath, + lldb::SymbolSharedCacheUse sc_mode); + static SharedCacheImageInfo + GetSharedCacheImageInfo(const UUID &uuid, lldb::SymbolSharedCacheUse sc_mode); static SharedCacheImageInfo - GetSharedCacheImageInfo(const ModuleSpec &spec, const UUID &sc_uuid, + GetSharedCacheImageInfo(ConstString filepath, const UUID &sc_uuid, + lldb::SymbolSharedCacheUse sc_mode); + static SharedCacheImageInfo + GetSharedCacheImageInfo(const UUID &uuid, const UUID &sc_uuid, lldb::SymbolSharedCacheUse sc_mode); static bool SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid, diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index a95e049eeaaf2..b22c9b93d3318 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -1031,37 +1031,44 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( } SharedCacheImageInfo -HostInfoMacOSX::GetSharedCacheImageInfo(const ModuleSpec &spec, SymbolSharedCacheUse sc_mode) { - SharedCacheImageInfo *entry = nullptr; - if (spec.GetUUID()) - entry = GetSharedCacheSingleton(sc_mode).GetHostSCUUIDToImageInfoMap().lookup( - spec.GetUUID()); - else - entry = GetSharedCacheSingleton(sc_mode).GetHostSCFilenameToImageInfoMap().lookup( - spec.GetFileSpec().GetPathAsConstString()); - if (entry) +HostInfoMacOSX::GetSharedCacheImageInfo(ConstString filepath, + SymbolSharedCacheUse sc_mode) { + if (SharedCacheImageInfo *entry = GetSharedCacheSingleton(sc_mode) + .GetHostSCFilenameToImageInfoMap() + .lookup(filepath)) return *entry; return {}; } SharedCacheImageInfo -HostInfoMacOSX::GetSharedCacheImageInfo(const ModuleSpec &spec, - const UUID &sc_uuid, +HostInfoMacOSX::GetSharedCacheImageInfo(const UUID &file_uuid, SymbolSharedCacheUse sc_mode) { - llvm::DenseMap<UUID, SharedCacheImageInfo *> *uuid_to_fileinfos = - GetSharedCacheSingleton(sc_mode).GetUUIDToImageInfoMap(sc_uuid); + if (SharedCacheImageInfo *entry = + GetSharedCacheSingleton(sc_mode).GetHostSCUUIDToImageInfoMap().lookup( + file_uuid)) + return *entry; + return {}; +} + +SharedCacheImageInfo HostInfoMacOSX::GetSharedCacheImageInfo( + ConstString filepath, const UUID &sc_uuid, SymbolSharedCacheUse sc_mode) { llvm::DenseMap<ConstString, SharedCacheImageInfo *> *filename_to_fileinfos = GetSharedCacheSingleton(sc_mode).GetFilenameToImageInfoMap(sc_uuid); - SharedCacheImageInfo *entry = nullptr; - if (uuid_to_fileinfos && spec.GetUUID()) - entry = uuid_to_fileinfos->lookup(spec.GetUUID()); - else if (filename_to_fileinfos) - entry = filename_to_fileinfos->lookup( - spec.GetFileSpec().GetPathAsConstString()); + if (filename_to_fileinfos) + if (SharedCacheImageInfo *entry = filename_to_fileinfos->lookup(filepath)) + return *entry; - if (entry) - return *entry; + return {}; +} + +SharedCacheImageInfo HostInfoMacOSX::GetSharedCacheImageInfo( + const UUID &file_uuid, const UUID &sc_uuid, SymbolSharedCacheUse sc_mode) { + llvm::DenseMap<UUID, SharedCacheImageInfo *> *uuid_to_fileinfos = + GetSharedCacheSingleton(sc_mode).GetUUIDToImageInfoMap(sc_uuid); + if (uuid_to_fileinfos) + if (SharedCacheImageInfo *entry = uuid_to_fileinfos->lookup(file_uuid)) + return *entry; return {}; } diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp index 45059ace6b415..eb9f49aef2069 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -147,11 +147,17 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo( if (GetSharedCacheInformation(sc_base_addr, sc_uuid, using_sc, private_sc, sc_path) && sc_uuid) { - image_info = - HostInfo::GetSharedCacheImageInfo(module_spec, sc_uuid, sc_mode); + if (module_spec.GetUUID()) + image_info = HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(), + sc_uuid, sc_mode); + + else + image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPathAsConstString(), sc_uuid, sc_mode); } else { // Fall back to looking lldb's own shared cache by filename - image_info = HostInfo::GetSharedCacheImageInfo(module_spec, sc_mode); + image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPathAsConstString(), sc_mode); } // If we found it and it has the correct UUID, let's proceed with diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp index d1a1abca00091..6b0e8514342b2 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp @@ -325,14 +325,20 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache( FileSpec sc_path; if (process->GetDynamicLoader()->GetSharedCacheInformation( sc_base_addr, sc_uuid, using_sc, private_sc, sc_path)) { - image_info = - HostInfo::GetSharedCacheImageInfo(module_spec, sc_uuid, sc_mode); + if (module_spec.GetUUID()) + image_info = HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(), + sc_uuid, sc_mode); + else + image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPathAsConstString(), sc_uuid, + sc_mode); } } // Fall back to looking for the file in lldb's own shared cache. if (!image_info.GetUUID()) - image_info = HostInfo::GetSharedCacheImageInfo(module_spec, sc_mode); + image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPathAsConstString(), sc_mode); // If we found it and it has the correct UUID, let's proceed with // creating a module from the memory contents. diff --git a/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp index cbdf7c8128b2e..5c1aaac886d6c 100644 --- a/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp +++ b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp @@ -206,8 +206,8 @@ std::optional<ModuleSpec> SymbolLocatorDebugSymbols::LocateExecutableObjectFile( SymbolSharedCacheUse sc_mode = ModuleList::GetGlobalModuleListProperties() .GetSharedCacheBinaryLoading(); - SharedCacheImageInfo image_info = - HostInfo::GetSharedCacheImageInfo(module_spec, sc_mode); + SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPathAsConstString(), sc_mode); // If we found it and it has the correct UUID, let's proceed with // creating a module from the memory contents. @@ -652,8 +652,8 @@ static int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, SymbolSharedCacheUse sc_mode = ModuleList::GetGlobalModuleListProperties() .GetSharedCacheBinaryLoading(); - SharedCacheImageInfo image_info = - HostInfo::GetSharedCacheImageInfo(module_spec, sc_mode); + SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPathAsConstString(), sc_mode); // If we found it and it has the correct UUID, let's proceed with // creating a module from the memory contents. diff --git a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp index acedf9a3d19d3..f4cf3c17e554b 100644 --- a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp +++ b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp @@ -39,10 +39,9 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) { Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch)); - ModuleSpec mod_spec; - mod_spec.GetFileSpec() = FileSpec("/usr/lib/libobjc.A.dylib"); SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( - mod_spec, lldb::eSymbolSharedCacheUseHostSharedCache); + ConstString("/usr/lib/libobjc.A.dylib"), + lldb::eSymbolSharedCacheUseHostSharedCache); EXPECT_TRUE(image_info.GetUUID()); EXPECT_TRUE(image_info.GetExtractor()); @@ -89,11 +88,10 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) { } TEST_F(ObjectFileMachOTest, IndirectSymbolsInTheSharedCache) { - ModuleSpec mod_spec; - mod_spec.GetFileSpec() = - FileSpec("/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit"); SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( - mod_spec, lldb::eSymbolSharedCacheUseHostSharedCache); + ConstString( + "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit"), + lldb::eSymbolSharedCacheUseHostSharedCache); ModuleSpec spec(FileSpec(), UUID(), image_info.GetExtractor()); lldb::ModuleSP module = std::make_shared<Module>(spec); >From 43ab314a69955d476fbd269c8ba3d8ab2afac6b5 Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 18:25:36 -0800 Subject: [PATCH 14/19] Update lldb/include/lldb/Host/HostInfoBase.h Co-authored-by: Jonas Devlieghere <[email protected]> --- lldb/include/lldb/Host/HostInfoBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index e355a65520f23..239f1fd6a2ada 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -49,7 +49,7 @@ struct SharedCacheImageInfo { m_extractor_sp = m_create_data_extractor(m_image_baton); return m_extractor_sp; } - lldb_private::ConstString GetFilename() const { return m_filename; } + ConstString GetFilename() const { return m_filename; } const UUID &GetUUID() const { return m_uuid; } void *GetImageBaton(); void SetExtractor(lldb::DataExtractorSP extractor_sp) { >From 3fc131784764d105dcb2f43e7ecec5e52b731334 Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Fri, 13 Feb 2026 18:48:34 -0800 Subject: [PATCH 15/19] ws fix --- lldb/include/lldb/Host/HostInfoBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index 239f1fd6a2ada..cfc41581636b2 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -49,7 +49,7 @@ struct SharedCacheImageInfo { m_extractor_sp = m_create_data_extractor(m_image_baton); return m_extractor_sp; } - ConstString GetFilename() const { return m_filename; } + ConstString GetFilename() const { return m_filename; } const UUID &GetUUID() const { return m_uuid; } void *GetImageBaton(); void SetExtractor(lldb::DataExtractorSP extractor_sp) { >From d57478704ae65dc4a500e679cd444179e07e41db Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Sun, 15 Feb 2026 15:16:04 -0800 Subject: [PATCH 16/19] Don't have ProcessGDBRemote index the inferior shared cache when the `symbols.shared-cache-binary-loading` setting indicates not to. A couple of fixes for handling multiple shared caches; I had an accidental assumption that there was only the host SC still, and the entries vector needs to be per-SC-UUID, not global, or it could be copied as shared caches are added and the old indexes would become invalid. --- .../Host/macosx/objcxx/HostInfoMacOSX.mm | 66 +++++++++++++------ .../Process/gdb-remote/ProcessGDBRemote.cpp | 17 +++-- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index b22c9b93d3318..39a11089a0b98 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -718,7 +718,10 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache, void CreateSharedCacheInfoLLDBsVirtualMemory(); bool CreateHostSharedCacheImageList(); - std::vector<SharedCacheImageInfo> m_file_infos; + // These three ivars have an initial key of a shared cache UUID. + // All of the entries for a given shared cache are in m_file_infos. + // m_filename_map and m_uuid_map have pointers into those entries. + llvm::SmallDenseMap<UUID, std::vector<SharedCacheImageInfo>> m_file_infos; llvm::SmallDenseMap<UUID, llvm::DenseMap<ConstString, SharedCacheImageInfo *>> m_filename_map; llvm::SmallDenseMap<UUID, llvm::DenseMap<UUID, SharedCacheImageInfo *>> @@ -749,9 +752,6 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache, _dyld_get_shared_cache_uuid(dsc_uuid); m_host_uuid = UUID(dsc_uuid); - // In macOS 26, a shared cache has around 3500 files. - m_file_infos.reserve(4000); - // Don't scan/index lldb's own shared cache at all, in-memory or // via libdyld SPI. if (sc_mode == eSymbolSharedCacheUseInferiorSharedCacheOnly) @@ -865,7 +865,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( // Scan the binaries in the specified shared cache filepath // if the UUID matches, using the macOS 26.4 libdyld SPI, // create a new entry in m_caches. -bool SharedCacheInfo::CreateSharedCacheImageList(UUID uuid, +bool SharedCacheInfo::CreateSharedCacheImageList(UUID sc_uuid, std::string filepath) { if (!m_dyld_image_retain_4HWTrace || !m_dyld_image_release_4HWTrace || !m_dyld_image_segment_data_4HWTrace) @@ -875,19 +875,30 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( return false; Log *log = GetLog(LLDBLog::Modules); + + // Have we already indexed this shared cache. + if (m_file_infos.contains(sc_uuid)) { + LLDB_LOGF(log, "Have already indexed shared cache UUID %s", + sc_uuid.GetAsString().c_str()); + return true; + } + LLDB_LOGF(log, "Opening shared cache at %s to check for matching UUID %s", - filepath.c_str(), uuid.GetAsString().c_str()); + filepath.c_str(), sc_uuid.GetAsString().c_str()); __block bool return_failed = false; dyld_shared_cache_for_file(filepath.c_str(), ^(dyld_shared_cache_t cache) { - uuid_t sc_uuid; - dyld_shared_cache_copy_uuid(cache, &sc_uuid); - UUID this_cache(sc_uuid, sizeof(uuid_t)); - if (this_cache != uuid) { + uuid_t uuid; + dyld_shared_cache_copy_uuid(cache, &uuid); + UUID this_cache(uuid, sizeof(uuid_t)); + if (this_cache != sc_uuid) { return_failed = true; return; } + // In macOS 26, a shared cache has around 3500 files. + m_file_infos[sc_uuid].reserve(4000); + dyld_shared_cache_for_each_image(cache, ^(dyld_image_t image) { uuid_t uuid_tmp; if (!dyld_image_copy_uuid(image, &uuid_tmp)) @@ -903,7 +914,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( (void *)image); m_dyld_image_retain_4HWTrace(image); - m_file_infos.push_back(SharedCacheImageInfo( + m_file_infos[sc_uuid].push_back(SharedCacheImageInfo( installname, image_uuid, map_shared_cache_binary_segments, image)); }); }); @@ -912,11 +923,11 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( // Vector of SharedCacheImageInfos has been fully populated, we can // take pointers to the objects now. - size_t file_info_size = m_file_infos.size(); + size_t file_info_size = m_file_infos[sc_uuid].size(); for (size_t i = 0; i < file_info_size; i++) { - SharedCacheImageInfo *entry = &m_file_infos[i]; - m_filename_map[m_host_uuid][entry->GetFilename()] = entry; - m_uuid_map[m_host_uuid][entry->GetUUID()] = entry; + SharedCacheImageInfo *entry = &m_file_infos[sc_uuid][i]; + m_filename_map[sc_uuid][entry->GetFilename()] = entry; + m_uuid_map[sc_uuid][entry->GetUUID()] = entry; } return true; @@ -965,6 +976,9 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( if (!shared_cache) return false; + // In macOS 26, a shared cache has around 3500 files. + m_file_infos[m_host_uuid].reserve(4000); + dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) { __block uint64_t minVmAddr = UINT64_MAX; __block uint64_t maxVmAddr = 0; @@ -986,9 +1000,18 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( // Copy the filename into the const string pool to // ensure lifetime. ConstString installname(dyld_image_get_installname(image)); - m_caches[m_host_uuid][installname.GetStringRef()] = - SharedCacheImageInfo{UUID(uuid, 16), extractor_sp}; + m_file_infos[m_host_uuid].push_back(SharedCacheImageInfo( + SharedCacheImageInfo{UUID(uuid, 16), extractor_sp})); }); + + // std::vector of SharedCacheImageInfos has been fully populated, we can + // take pointers to the objects now. + size_t file_info_size = m_file_infos[m_host_uuid].size(); + for (size_t i = 0; i < file_info_size; i++) { + SharedCacheImageInfo *entry = &m_file_infos[m_host_uuid][i]; + m_filename_map[m_host_uuid][entry->GetFilename()] = entry; + m_uuid_map[m_host_uuid][entry->GetUUID()] = entry; + } return true; #endif return false; @@ -1002,6 +1025,9 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( uint8_t *shared_cache_start = _dyld_get_shared_cache_range(&shared_cache_size); + // In macOS 26, a shared cache has around 3500 files. + m_file_infos[m_host_uuid].reserve(4000); + dyld_shared_cache_iterate_text( m_host_uuid.GetBytes().data(), ^(const dyld_shared_cache_dylib_text_info *info) { @@ -1011,15 +1037,15 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( lldb::DataExtractorSP extractor_sp = std::make_shared<DataExtractor>(buffer_sp); ConstString filepath(info->path); - m_file_infos.push_back(SharedCacheImageInfo( + m_file_infos[m_host_uuid].push_back(SharedCacheImageInfo( filepath, UUID(info->dylibUuid, 16), extractor_sp)); }); // std::vector of SharedCacheImageInfos has been fully populated, we can // take pointers to the objects now. - size_t file_info_size = m_file_infos.size(); + size_t file_info_size = m_file_infos[m_host_uuid].size(); for (size_t i = 0; i < file_info_size; i++) { - SharedCacheImageInfo *entry = &m_file_infos[i]; + SharedCacheImageInfo *entry = &m_file_infos[m_host_uuid][i]; m_filename_map[m_host_uuid][entry->GetFilename()] = entry; m_uuid_map[m_host_uuid][entry->GetUUID()] = entry; } diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index c8667ee247f23..edd0e199cfa24 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4375,12 +4375,19 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() { FileSpec sc_path( dict->GetValueForKey("shared_cache_path")->GetStringValue()); - // Attempt to open the shared cache at sc_path, and - // if the uuid matches, index all the files. - HostInfo::SharedCacheIndexFiles( - sc_path, uuid, + SymbolSharedCacheUse sc_mode = ModuleList::GetGlobalModuleListProperties() - .GetSharedCacheBinaryLoading()); + .GetSharedCacheBinaryLoading(); + + if (sc_mode == eSymbolSharedCacheUseHostAndInferiorSharedCache || + sc_mode == eSymbolSharedCacheUseInferiorSharedCacheOnly) { + // Attempt to open the shared cache at sc_path, and + // if the uuid matches, index all the files. + HostInfo::SharedCacheIndexFiles( + sc_path, uuid, + ModuleList::GetGlobalModuleListProperties() + .GetSharedCacheBinaryLoading()); + } } m_shared_cache_info_sp = response_sp; } >From d6cbeda6b5f6f447b42fe109711ff44b85e07c00 Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Sun, 15 Feb 2026 15:18:14 -0800 Subject: [PATCH 17/19] cleanup --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index edd0e199cfa24..57d86ef71eecc 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4383,10 +4383,7 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() { sc_mode == eSymbolSharedCacheUseInferiorSharedCacheOnly) { // Attempt to open the shared cache at sc_path, and // if the uuid matches, index all the files. - HostInfo::SharedCacheIndexFiles( - sc_path, uuid, - ModuleList::GetGlobalModuleListProperties() - .GetSharedCacheBinaryLoading()); + HostInfo::SharedCacheIndexFiles(sc_path, uuid, sc_mode); } } m_shared_cache_info_sp = response_sp; >From c6a2fa21aaa689e180c625511ed8b2e310e618ed Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Sun, 15 Feb 2026 18:06:04 -0800 Subject: [PATCH 18/19] syntax fix for when building against internal SDK. --- lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index 39a11089a0b98..2c3ed072b850a 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -1000,8 +1000,8 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( // Copy the filename into the const string pool to // ensure lifetime. ConstString installname(dyld_image_get_installname(image)); - m_file_infos[m_host_uuid].push_back(SharedCacheImageInfo( - SharedCacheImageInfo{UUID(uuid, 16), extractor_sp})); + m_file_infos[m_host_uuid].push_back( + SharedCacheImageInfo(installname, UUID(uuid, 16), extractor_sp)); }); // std::vector of SharedCacheImageInfos has been fully populated, we can >From 55699821b0976b9179bece73b2f526b1ac638535 Mon Sep 17 00:00:00 2001 From: Jason Molenda <[email protected]> Date: Mon, 16 Feb 2026 17:18:34 -0800 Subject: [PATCH 19/19] The SourceCacheInfo class inside HostInfoMacOSX has three DenseMap's with the shared cache UUID being the primary key. They would pass out pointers to these map values to HostInfoMacOSX methods. Jonas was concerned about this, and he is right. I've kept all references to these DenseMaps local to SourceCacheInfo methods. I've added a mutex to SourceCacheInfo and lock around access to that DenseMap so the memory isn't mutated while we're reading a binary on one thread, while a new shared cache is being indexed & added to the DenseMap on another thread. SourceCacheInfo creates one DenseMap, `m_file_infos`, which has a vector of file entries. Also `m_filename_map` and `m_uuid_map` which are maps into that vector by filename or uuid. I was storing pointers to the vector, but Jonas thinks this vector could be moved as the DenseMap is reallocated, so I changed these to indexes. --- .../Host/macosx/objcxx/HostInfoMacOSX.mm | 90 ++++++++----------- 1 file changed, 38 insertions(+), 52 deletions(-) diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index 2c3ed072b850a..a46c97514f67e 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -685,26 +685,28 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache, namespace { class SharedCacheInfo { public: - llvm::DenseMap<ConstString, SharedCacheImageInfo *> & - GetHostSCFilenameToImageInfoMap() { - return m_filename_map[m_host_uuid]; - } - llvm::DenseMap<UUID, SharedCacheImageInfo *> &GetHostSCUUIDToImageInfoMap() { - return m_uuid_map[m_host_uuid]; - } - - llvm::DenseMap<ConstString, SharedCacheImageInfo *> * - GetFilenameToImageInfoMap(const UUID &sc_uuid) { - if (m_filename_map.contains(sc_uuid)) - return &m_filename_map[sc_uuid]; - return nullptr; + SharedCacheImageInfo GetByFilename(UUID sc_uuid, ConstString filename) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (!sc_uuid) + sc_uuid = m_host_uuid; + if (!m_filename_map.contains(sc_uuid)) + return {}; + if (!m_filename_map[sc_uuid].contains(filename)) + return {}; + size_t idx = m_filename_map[sc_uuid][filename]; + return m_file_infos[sc_uuid][idx]; } - llvm::DenseMap<UUID, SharedCacheImageInfo *> * - GetUUIDToImageInfoMap(const UUID &sc_uuid) { - if (m_uuid_map.contains(sc_uuid)) - return &m_uuid_map[sc_uuid]; - return nullptr; + SharedCacheImageInfo GetByUUID(UUID sc_uuid, UUID file_uuid) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (!sc_uuid) + sc_uuid = m_host_uuid; + if (!m_uuid_map.contains(sc_uuid)) + return {}; + if (!m_uuid_map[sc_uuid].contains(file_uuid)) + return {}; + size_t idx = m_uuid_map[sc_uuid][file_uuid]; + return m_file_infos[sc_uuid][idx]; } /// Given the UUID and filepath to a shared cache on the local debug host @@ -722,13 +724,13 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache, // All of the entries for a given shared cache are in m_file_infos. // m_filename_map and m_uuid_map have pointers into those entries. llvm::SmallDenseMap<UUID, std::vector<SharedCacheImageInfo>> m_file_infos; - llvm::SmallDenseMap<UUID, llvm::DenseMap<ConstString, SharedCacheImageInfo *>> - m_filename_map; - llvm::SmallDenseMap<UUID, llvm::DenseMap<UUID, SharedCacheImageInfo *>> - m_uuid_map; + llvm::SmallDenseMap<UUID, llvm::DenseMap<ConstString, size_t>> m_filename_map; + llvm::SmallDenseMap<UUID, llvm::DenseMap<UUID, size_t>> m_uuid_map; UUID m_host_uuid; + std::recursive_mutex m_mutex; + // macOS 26.4 and newer void (*m_dyld_image_retain_4HWTrace)(void *image); void (*m_dyld_image_release_4HWTrace)(void *image); @@ -867,6 +869,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( // create a new entry in m_caches. bool SharedCacheInfo::CreateSharedCacheImageList(UUID sc_uuid, std::string filepath) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_dyld_image_retain_4HWTrace || !m_dyld_image_release_4HWTrace || !m_dyld_image_segment_data_4HWTrace) return false; @@ -926,8 +929,8 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( size_t file_info_size = m_file_infos[sc_uuid].size(); for (size_t i = 0; i < file_info_size; i++) { SharedCacheImageInfo *entry = &m_file_infos[sc_uuid][i]; - m_filename_map[sc_uuid][entry->GetFilename()] = entry; - m_uuid_map[sc_uuid][entry->GetUUID()] = entry; + m_filename_map[sc_uuid][entry->GetFilename()] = i; + m_uuid_map[sc_uuid][entry->GetUUID()] = i; } return true; @@ -936,6 +939,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( // Get the filename and uuid of lldb's own shared cache, scan // the files in it using the macOS 26.4 and newer libdyld SPI. bool SharedCacheInfo::CreateHostSharedCacheImageList() { + std::lock_guard<std::recursive_mutex> guard(m_mutex); std::string host_shared_cache_file = dyld_shared_cache_file_path(); __block UUID host_sc_uuid; dyld_shared_cache_for_file(host_shared_cache_file.c_str(), @@ -955,6 +959,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( // libdyld SPI present on macOS 12 and newer, when building against // the internal SDK, and add an entry to the m_caches map. bool SharedCacheInfo::CreateSharedCacheInfoWithInstrospectionSPIs() { + std::lock_guard<std::recursive_mutex> guard(m_mutex); #if defined(SDK_HAS_NEW_DYLD_INTROSPECTION_SPIS) dyld_process_t dyld_process = dyld_process_create_for_current_task(); if (!dyld_process) @@ -1009,8 +1014,8 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( size_t file_info_size = m_file_infos[m_host_uuid].size(); for (size_t i = 0; i < file_info_size; i++) { SharedCacheImageInfo *entry = &m_file_infos[m_host_uuid][i]; - m_filename_map[m_host_uuid][entry->GetFilename()] = entry; - m_uuid_map[m_host_uuid][entry->GetUUID()] = entry; + m_filename_map[m_host_uuid][entry->GetFilename()] = i; + m_uuid_map[m_host_uuid][entry->GetUUID()] = i; } return true; #endif @@ -1021,6 +1026,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( // libdyld SPI available on macOS 10.13 or newer, add an entry to // m_caches. void SharedCacheInfo::CreateSharedCacheInfoLLDBsVirtualMemory() { + std::lock_guard<std::recursive_mutex> guard(m_mutex); size_t shared_cache_size; uint8_t *shared_cache_start = _dyld_get_shared_cache_range(&shared_cache_size); @@ -1046,8 +1052,8 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( size_t file_info_size = m_file_infos[m_host_uuid].size(); for (size_t i = 0; i < file_info_size; i++) { SharedCacheImageInfo *entry = &m_file_infos[m_host_uuid][i]; - m_filename_map[m_host_uuid][entry->GetFilename()] = entry; - m_uuid_map[m_host_uuid][entry->GetUUID()] = entry; + m_filename_map[m_host_uuid][entry->GetFilename()] = i; + m_uuid_map[m_host_uuid][entry->GetUUID()] = i; } } @@ -1059,43 +1065,23 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)( SharedCacheImageInfo HostInfoMacOSX::GetSharedCacheImageInfo(ConstString filepath, SymbolSharedCacheUse sc_mode) { - if (SharedCacheImageInfo *entry = GetSharedCacheSingleton(sc_mode) - .GetHostSCFilenameToImageInfoMap() - .lookup(filepath)) - return *entry; - return {}; + return GetSharedCacheSingleton(sc_mode).GetByFilename(UUID(), filepath); } SharedCacheImageInfo HostInfoMacOSX::GetSharedCacheImageInfo(const UUID &file_uuid, SymbolSharedCacheUse sc_mode) { - if (SharedCacheImageInfo *entry = - GetSharedCacheSingleton(sc_mode).GetHostSCUUIDToImageInfoMap().lookup( - file_uuid)) - return *entry; - return {}; + return GetSharedCacheSingleton(sc_mode).GetByUUID(UUID(), file_uuid); } SharedCacheImageInfo HostInfoMacOSX::GetSharedCacheImageInfo( ConstString filepath, const UUID &sc_uuid, SymbolSharedCacheUse sc_mode) { - llvm::DenseMap<ConstString, SharedCacheImageInfo *> *filename_to_fileinfos = - GetSharedCacheSingleton(sc_mode).GetFilenameToImageInfoMap(sc_uuid); - - if (filename_to_fileinfos) - if (SharedCacheImageInfo *entry = filename_to_fileinfos->lookup(filepath)) - return *entry; - - return {}; + return GetSharedCacheSingleton(sc_mode).GetByFilename(sc_uuid, filepath); } SharedCacheImageInfo HostInfoMacOSX::GetSharedCacheImageInfo( const UUID &file_uuid, const UUID &sc_uuid, SymbolSharedCacheUse sc_mode) { - llvm::DenseMap<UUID, SharedCacheImageInfo *> *uuid_to_fileinfos = - GetSharedCacheSingleton(sc_mode).GetUUIDToImageInfoMap(sc_uuid); - if (uuid_to_fileinfos) - if (SharedCacheImageInfo *entry = uuid_to_fileinfos->lookup(file_uuid)) - return *entry; - return {}; + return GetSharedCacheSingleton(sc_mode).GetByUUID(sc_uuid, file_uuid); } bool HostInfoMacOSX::SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid, _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
