https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/180323

>From dc41c1eb771c766e6213c55c1562b6af1f1220a1 Mon Sep 17 00:00:00 2001
From: Jason Molenda <[email protected]>
Date: Fri, 6 Feb 2026 22:08:00 -0800
Subject: [PATCH 1/7] [lldb] Get shared cache path from inferior, open

Get the shared cache filepath and uuid that the inferior process
is using from debugserver, try to open that shared cache on the
lldb host mac and if the UUID matches, index all of the binaries
in that shared cache.  When looking for binaries loaded in the
process, get them from the already-indexed shared cache.

Every time a binary is loaded, PlatformMacOSX may query the shared
cache filepath and uuid from the Process, and pass that to
HostInfo::GetSharedCacheImageInfo() if available (else fall back
to the old HostInfo::GetSharedCacheImageInfo method which only looks
at lldb's own shared cache), to get the file being requested.

ProcessGDBRemote caches the shared cache filepath and uuid from the
inferior, once it has a non-zero UUID.  I added a lock for this
ivar specifically, so I don't have 20 threads all asking for the
shared cache information from debugserver and updating the cached
answer.  If we never get back a non-zero UUID shared cache reply,
we will re-query at every library loaded notification.  debugserver
has been providing the shared cache UUID since 2013, although I
only added the shared cache filepath field last November.

Note that a process will not report its shared cache filepath or
uuid at initial launch.  As dyld gets a chance to execute a bit,
it will start returning binaries -- it will be available at the
point when libraries start loading. (it won't be available yet when
the binary & dyld are the only two binaries loaded in the process)

I tested this by disabling lldb's scan of its own shared cache
pre-execution -- only loading the system shared cache when the
inferior process reports that it is using that.  I got 6-7 additional
testsuite failures running lldb like that, because no system binaries
were loaded before exeuction start, and the tests assumed they
would be.

rdar://148939795
---
 lldb/include/lldb/Host/HostInfoBase.h         | 16 ++++
 .../include/lldb/Host/macosx/HostInfoMacOSX.h |  5 ++
 lldb/include/lldb/Target/DynamicLoader.h      | 12 ++-
 .../Host/macosx/objcxx/HostInfoMacOSX.mm      | 52 +++++++++++--
 .../MacOSX-DYLD/DynamicLoaderDarwin.cpp       | 16 +++-
 .../MacOSX-DYLD/DynamicLoaderMacOS.cpp        | 10 ++-
 .../MacOSX-DYLD/DynamicLoaderMacOS.h          | 10 ++-
 .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp   |  2 +-
 .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h     |  3 +-
 .../ObjectFile/Mach-O/ObjectFileMachO.cpp     |  3 +-
 .../Platform/MacOSX/PlatformDarwinDevice.cpp  | 22 +++++-
 .../Platform/MacOSX/PlatformDarwinDevice.h    |  3 +-
 .../Platform/MacOSX/PlatformMacOSX.cpp        | 10 +--
 .../MacOSX/PlatformRemoteDarwinDevice.cpp     |  2 +-
 .../Process/gdb-remote/ProcessGDBRemote.cpp   | 74 +++++++++++--------
 .../Process/gdb-remote/ProcessGDBRemote.h     |  2 +
 .../platform/basic/TestPlatformCommand.py     |  4 +-
 17 files changed, 184 insertions(+), 62 deletions(-)

diff --git a/lldb/include/lldb/Host/HostInfoBase.h 
b/lldb/include/lldb/Host/HostInfoBase.h
index 149810ff53924..fc9ab96676341 100644
--- a/lldb/include/lldb/Host/HostInfoBase.h
+++ b/lldb/include/lldb/Host/HostInfoBase.h
@@ -190,6 +190,22 @@ class HostInfoBase {
     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, UUID &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
+  /// did not match.
+  static bool SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid) {
+    return false;
+  }
+
   /// Returns the distribution id of the host
   ///
   /// This will be something like "ubuntu", "fedora", etc. on Linux.
diff --git a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h 
b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
index 734a394c18679..78f8344aefd13 100644
--- a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
+++ b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
@@ -45,6 +45,11 @@ class HostInfoMacOSX : public HostInfoPosix {
   static SharedCacheImageInfo
   GetSharedCacheImageInfo(llvm::StringRef image_name);
 
+  static SharedCacheImageInfo
+  GetSharedCacheImageInfo(llvm::StringRef image_name, UUID &uuid);
+
+  static bool SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid);
+
 protected:
   static bool ComputeSupportExeDirectory(FileSpec &file_spec);
   static void ComputeHostArchitectureSupport(ArchSpec &arch_32,
diff --git a/lldb/include/lldb/Target/DynamicLoader.h 
b/lldb/include/lldb/Target/DynamicLoader.h
index 7f2652bb28727..04fd7556e1068 100644
--- a/lldb/include/lldb/Target/DynamicLoader.h
+++ b/lldb/include/lldb/Target/DynamicLoader.h
@@ -310,12 +310,18 @@ class DynamicLoader : public PluginInterface {
   ///     private shared cache.
   ///     If this information cannot be fetched, eLazyBoolCalculate.
   ///
+  /// \param[out] shared_cache_path
+  ///     A FileSpec representing the shared cache path being run
+  ///     in the inferior process.
+  ///
   /// \return
   ///     Returns false if this DynamicLoader cannot gather information
   ///     about the shared cache / has no concept of a shared cache.
-  virtual bool GetSharedCacheInformation(lldb::addr_t &base_address, UUID 
&uuid,
-                                         LazyBool &using_shared_cache,
-                                         LazyBool &private_shared_cache) {
+  virtual bool
+  GetSharedCacheInformation(lldb::addr_t &base_address, UUID &uuid,
+                            LazyBool &using_shared_cache,
+                            LazyBool &private_shared_cache,
+                            lldb_private::FileSpec &shared_cache_path) {
     base_address = LLDB_INVALID_ADDRESS;
     uuid.Clear();
     using_shared_cache = eLazyBoolCalculate;
diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm 
b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index e8f416270cdb8..6d1755f346df8 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -688,6 +688,18 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t 
cache,
     return m_caches[m_host_uuid];
   }
 
+  bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images, UUID &uuid) {
+    if (m_caches.find(uuid) != m_caches.end()) {
+      *images = &m_caches[uuid];
+      return true;
+    }
+    return false;
+  }
+
+  // Given the UUID and filepath to a shared cache on the local debug host
+  // system, open it and add all of the binary images to m_caches.
+  bool CreateSharedCacheImageList(UUID uuid, std::string filepath);
+
   SharedCacheInfo();
 
 private:
@@ -695,10 +707,6 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t 
cache,
   void CreateSharedCacheInfoLLDBsVirtualMemory();
   bool CreateHostSharedCacheImageList();
 
-  // Given the UUID and filepath to a shared cache on the local debug host
-  // system, open it and add all of the binary images to m_caches.
-  bool CreateSharedCacheImageList(UUID uuid, std::string filepath);
-
   std::map<UUID, llvm::StringMap<SharedCacheImageInfo>> m_caches;
   UUID m_host_uuid;
 
@@ -829,6 +837,13 @@ static dispatch_data_t 
(*g_dyld_image_segment_data_4HWTrace)(
       !m_dyld_image_segment_data_4HWTrace)
     return false;
 
+  if (filepath.empty())
+    return false;
+
+  Log *log = GetLog(LLDBLog::Modules);
+  LLDB_LOGF(log, "Opening shared cache at %s to check for matching UUID %s",
+            filepath.c_str(), 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;
@@ -952,8 +967,33 @@ static dispatch_data_t 
(*g_dyld_image_segment_data_4HWTrace)(
       });
 }
 
+SharedCacheInfo &GetSharedCacheSingleton() {
+  static SharedCacheInfo g_shared_cache_info;
+  return g_shared_cache_info;
+}
+
 SharedCacheImageInfo
 HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name) {
-  static SharedCacheInfo g_shared_cache_info;
-  return g_shared_cache_info.GetImages().lookup(image_name);
+  return GetSharedCacheSingleton().GetImages().lookup(image_name);
+}
+
+SharedCacheImageInfo
+HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name,
+                                        UUID &uuid) {
+  llvm::StringMap<SharedCacheImageInfo> *shared_cache_info;
+  if (GetSharedCacheSingleton().GetImages(&shared_cache_info, uuid))
+    return shared_cache_info->lookup(image_name);
+  else
+    return {};
+}
+
+bool HostInfoMacOSX::SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid) {
+  // There is a libdyld SPI to iterate over all installed shared caches,
+  // but it can have performance problems if an older Simulator SDK shared
+  // cache is installed.  So require that we are given a filepath of
+  // the shared cache.
+  if (FileSystem::Instance().Exists(filepath))
+    return GetSharedCacheSingleton().CreateSharedCacheImageList(
+        uuid, filepath.GetPath());
+  return false;
 }
diff --git 
a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index 00cae1c6cea1e..0a8aa51a1469c 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -135,8 +135,20 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
     // 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 =
-        HostInfo::GetSharedCacheImageInfo(module_spec.GetFileSpec().GetPath());
+    SharedCacheImageInfo image_info;
+    addr_t sc_base_addr;
+    UUID sc_uuid;
+    LazyBool using_sc;
+    LazyBool private_sc;
+    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
+      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/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
index ce1a0975260c9..97a487bf79e4d 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -691,7 +691,7 @@ Status DynamicLoaderMacOS::CanLoadImage() {
 
 bool DynamicLoaderMacOS::GetSharedCacheInformation(
     lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
-    LazyBool &private_shared_cache) {
+    LazyBool &private_shared_cache, FileSpec &shared_cache_path) {
   base_address = LLDB_INVALID_ADDRESS;
   uuid.Clear();
   using_shared_cache = eLazyBoolCalculate;
@@ -710,6 +710,7 @@ bool DynamicLoaderMacOS::GetSharedCacheInformation(
 
     if (info_dict && info_dict->HasKey("shared_cache_uuid") &&
         info_dict->HasKey("no_shared_cache") &&
+        info_dict->HasKey("shared_cache_private_cache") &&
         info_dict->HasKey("shared_cache_base_address")) {
       base_address = info_dict->GetValueForKey("shared_cache_base_address")
                          ->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS);
@@ -726,7 +727,12 @@ bool DynamicLoaderMacOS::GetSharedCacheInformation(
         private_shared_cache = eLazyBoolYes;
       else
         private_shared_cache = eLazyBoolNo;
-
+      if (info_dict->HasKey("shared_cache_path")) {
+        std::string filepath = info_dict->GetValueForKey("shared_cache_path")
+                                   ->GetStringValue()
+                                   .str();
+        shared_cache_path.SetPath(filepath);
+      }
       return true;
     }
   }
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
index bd2c2e0bac538..9bb50de3eadb3 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
@@ -54,10 +54,12 @@ class DynamicLoaderMacOS : public 
lldb_private::DynamicLoaderDarwin {
 
   lldb_private::Status CanLoadImage() override;
 
-  bool GetSharedCacheInformation(
-      lldb::addr_t &base_address, lldb_private::UUID &uuid,
-      lldb_private::LazyBool &using_shared_cache,
-      lldb_private::LazyBool &private_shared_cache) override;
+  bool
+  GetSharedCacheInformation(lldb::addr_t &base_address,
+                            lldb_private::UUID &uuid,
+                            lldb_private::LazyBool &using_shared_cache,
+                            lldb_private::LazyBool &private_shared_cache,
+                            lldb_private::FileSpec &shared_cache_path) 
override;
 
   // PluginInterface protocol
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
diff --git 
a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index f839948660aa0..1ec91548a1866 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -1071,7 +1071,7 @@ Status DynamicLoaderMacOSXDYLD::CanLoadImage() {
 
 bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation(
     lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
-    LazyBool &private_shared_cache) {
+    LazyBool &private_shared_cache, FileSpec &shared_cache_filepath) {
   base_address = LLDB_INVALID_ADDRESS;
   uuid.Clear();
   using_shared_cache = eLazyBoolCalculate;
diff --git 
a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h 
b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
index ae7451722a8d7..e3f263a08d7df 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
@@ -61,7 +61,8 @@ class DynamicLoaderMacOSXDYLD : public 
lldb_private::DynamicLoaderDarwin {
   bool GetSharedCacheInformation(
       lldb::addr_t &base_address, lldb_private::UUID &uuid,
       lldb_private::LazyBool &using_shared_cache,
-      lldb_private::LazyBool &private_shared_cache) override;
+      lldb_private::LazyBool &private_shared_cache,
+      lldb_private::FileSpec &shared_cache_filepath) override;
 
   // PluginInterface protocol
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 
b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index c1729d7ef57ba..b188c3f6964b2 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5737,8 +5737,9 @@ void ObjectFileMachO::GetProcessSharedCacheUUID(Process 
*process,
     DynamicLoader *dl = process->GetDynamicLoader();
     LazyBool using_shared_cache;
     LazyBool private_shared_cache;
+    FileSpec sc_filepath;
     dl->GetSharedCacheInformation(base_addr, uuid, using_shared_cache,
-                                  private_shared_cache);
+                                  private_shared_cache, sc_filepath);
   }
   Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));
   LLDB_LOGF(
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp 
b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
index c1a04e801107e..59d2f9ed9d856 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
@@ -11,6 +11,7 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Host/HostInfo.h"
+#include "lldb/Target/DynamicLoader.h"
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
@@ -295,7 +296,8 @@ BringInRemoteFile(Platform *platform,
 
 lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache(
     const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
-    llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) {
+    llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr,
+    Process *process) {
 
   Log *log = GetLog(LLDBLog::Platform);
   LLDB_LOGF(log,
@@ -317,9 +319,21 @@ lldb_private::Status 
PlatformDarwinDevice::GetSharedModuleWithLocalCache(
     // 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 =
-        HostInfo::GetSharedCacheImageInfo(module_spec.GetFileSpec().GetPath());
+    SharedCacheImageInfo image_info;
+    if (process && process->GetDynamicLoader()) {
+      addr_t sc_base_addr;
+      UUID sc_uuid;
+      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);
+    }
+
+    if (!image_info.GetUUID())
+      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.h 
b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h
index e0142ab7ca4cb..d8ea1807edf14 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.h
@@ -26,7 +26,8 @@ class PlatformDarwinDevice : public PlatformDarwin {
 protected:
   virtual Status GetSharedModuleWithLocalCache(
       const ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
-      llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool 
*did_create_ptr);
+      llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr,
+      lldb_private::Process *process);
 
   struct SDKDirectoryInfo {
     SDKDirectoryInfo(const FileSpec &sdk_dir_spec);
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp 
b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
index e6ea75a35f921..bf653cd758295 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -183,8 +183,8 @@ lldb_private::Status PlatformMacOSX::GetSharedModule(
     const lldb_private::ModuleSpec &module_spec, Process *process,
     lldb::ModuleSP &module_sp,
     llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) {
-  Status error = GetSharedModuleWithLocalCache(module_spec, module_sp,
-                                               old_modules, did_create_ptr);
+  Status error = GetSharedModuleWithLocalCache(
+      module_spec, module_sp, old_modules, did_create_ptr, process);
 
   if (module_sp) {
     if (module_spec.GetArchitecture().GetCore() ==
@@ -197,9 +197,9 @@ lldb_private::Status PlatformMacOSX::GetSharedModule(
         lldb::ModuleSP x86_64_module_sp;
         llvm::SmallVector<lldb::ModuleSP, 1> old_x86_64_modules;
         bool did_create = false;
-        Status x86_64_error =
-            GetSharedModuleWithLocalCache(module_spec_x86_64, x86_64_module_sp,
-                                          &old_x86_64_modules, &did_create);
+        Status x86_64_error = GetSharedModuleWithLocalCache(
+            module_spec_x86_64, x86_64_module_sp, &old_x86_64_modules,
+            &did_create, process);
         if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) {
           module_sp = x86_64_module_sp;
           if (old_modules)
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp 
b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
index 021a526bb623b..2babfa0517ab5 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
@@ -261,7 +261,7 @@ Status PlatformRemoteDarwinDevice::GetSharedModule(
   // This may not be an SDK-related module.  Try whether we can bring in the
   // thing to our local cache.
   error = GetSharedModuleWithLocalCache(module_spec, module_sp, old_modules,
-                                        did_create_ptr);
+                                        did_create_ptr, process);
   if (error.Success())
     return error;
 
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp 
b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index e1f28674ae45c..eb85b9278c54b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -269,13 +269,14 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP 
target_sp,
       m_async_listener_sp(
           Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
       m_async_thread_state_mutex(), m_thread_ids(), m_thread_pcs(),
-      m_jstopinfo_sp(), m_jthreadsinfo_sp(), m_continue_c_tids(),
-      m_continue_C_tids(), m_continue_s_tids(), m_continue_S_tids(),
-      m_max_memory_size(0), m_remote_stub_max_memory_size(0),
-      m_addr_to_mmap_size(), m_thread_create_bp_sp(),
-      m_waiting_for_attach(false), m_command_sp(), m_breakpoint_pc_offset(0),
-      m_initial_tid(LLDB_INVALID_THREAD_ID), m_allow_flash_writes(false),
-      m_erased_flash_ranges(), m_vfork_in_progress_count(0) {
+      m_jstopinfo_sp(), m_jthreadsinfo_sp(), m_shared_cache_info_sp(),
+      m_shared_cache_info_mutex(), m_continue_c_tids(), m_continue_C_tids(),
+      m_continue_s_tids(), m_continue_S_tids(), m_max_memory_size(0),
+      m_remote_stub_max_memory_size(0), m_addr_to_mmap_size(),
+      m_thread_create_bp_sp(), m_waiting_for_attach(false), m_command_sp(),
+      m_breakpoint_pc_offset(0), m_initial_tid(LLDB_INVALID_THREAD_ID),
+      m_allow_flash_writes(false), m_erased_flash_ranges(),
+      m_vfork_in_progress_count(0) {
   m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
                                    "async thread should exit");
   m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
@@ -1248,6 +1249,7 @@ Status ProcessGDBRemote::WillResume() {
   m_continue_S_tids.clear();
   m_jstopinfo_sp.reset();
   m_jthreadsinfo_sp.reset();
+  m_shared_cache_info_sp.reset();
   return Status();
 }
 
@@ -4335,35 +4337,49 @@ StructuredData::ObjectSP 
ProcessGDBRemote::GetDynamicLoaderProcessState() {
 }
 
 StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {
-  StructuredData::ObjectSP object_sp;
+  std::lock_guard<std::recursive_mutex> guard(m_shared_cache_info_mutex);
   StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
 
-  if (m_gdb_comm.GetSharedCacheInfoSupported()) {
-    StreamString packet;
-    packet << "jGetSharedCacheInfo:";
-    args_dict->Dump(packet, false);
+  if (m_shared_cache_info_sp || !m_gdb_comm.GetSharedCacheInfoSupported())
+    return m_shared_cache_info_sp;
 
-    // FIXME the final character of a JSON dictionary, '}', is the escape
-    // character in gdb-remote binary mode.  lldb currently doesn't escape
-    // these characters in its packet output -- so we add the quoted version of
-    // the } character here manually in case we talk to a debugserver which un-
-    // escapes the characters at packet read time.
-    packet << (char)(0x7d ^ 0x20);
+  StreamString packet;
+  packet << "jGetSharedCacheInfo:";
+  args_dict->Dump(packet, false);
 
-    StringExtractorGDBRemote response;
-    response.SetResponseValidatorToJSON();
-    if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) 
==
-        GDBRemoteCommunication::PacketResult::Success) {
-      StringExtractorGDBRemote::ResponseType response_type =
-          response.GetResponseType();
-      if (response_type == StringExtractorGDBRemote::eResponse) {
-        if (!response.Empty()) {
-          object_sp = StructuredData::ParseJSON(response.GetStringRef());
-        }
+  StringExtractorGDBRemote response;
+  response.SetResponseValidatorToJSON();
+  if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==
+      GDBRemoteCommunication::PacketResult::Success) {
+    StringExtractorGDBRemote::ResponseType response_type =
+        response.GetResponseType();
+    if (response_type == StringExtractorGDBRemote::eResponse) {
+      if (response.Empty())
+        return {};
+      StructuredData::ObjectSP response_sp =
+          StructuredData::ParseJSON(response.GetStringRef());
+      if (!response_sp)
+        return {};
+      StructuredData::Dictionary *dict = response_sp->GetAsDictionary();
+      if (!dict)
+        return {};
+      if (!dict->HasKey("shared_cache_uuid"))
+        return {};
+      llvm::StringRef uuid_str;
+      if (!dict->GetValueForKeyAsString("shared_cache_uuid", uuid_str, "") ||
+          uuid_str == "00000000-0000-0000-0000-000000000000")
+        return {};
+      if (dict->HasKey("shared_cache_path")) {
+        UUID uuid;
+        uuid.SetFromStringRef(uuid_str);
+        FileSpec sc_path(
+            dict->GetValueForKey("shared_cache_path")->GetStringValue());
+        HostInfo::SharedCacheIndexFiles(sc_path, uuid);
       }
+      m_shared_cache_info_sp = response_sp;
     }
   }
-  return object_sp;
+  return m_shared_cache_info_sp;
 }
 
 Status ProcessGDBRemote::ConfigureStructuredData(
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h 
b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index db3c43284587b..dfee3928bb0d1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -297,6 +297,8 @@ class ProcessGDBRemote : public Process,
                                               // registers and memory for all
                                               // threads if "jThreadsInfo"
                                               // packet is supported
+  StructuredData::ObjectSP m_shared_cache_info_sp;
+  std::recursive_mutex m_shared_cache_info_mutex;
   tid_collection m_continue_c_tids;           // 'c' for continue
   tid_sig_collection m_continue_C_tids;       // 'C' for continue with signal
   tid_collection m_continue_s_tids;           // 's' for step
diff --git a/lldb/test/API/commands/platform/basic/TestPlatformCommand.py 
b/lldb/test/API/commands/platform/basic/TestPlatformCommand.py
index 1e1a476c44a92..e9e1b8f9ce796 100644
--- a/lldb/test/API/commands/platform/basic/TestPlatformCommand.py
+++ b/lldb/test/API/commands/platform/basic/TestPlatformCommand.py
@@ -71,8 +71,8 @@ def test_shell(self):
             self.expect("platform shell ls /", substrs=["cache", "dev", 
"system"])
             self.expect("shell ls /", substrs=["cache", "dev", "system"])
         else:
-            self.expect("platform shell ls /", substrs=["dev", "tmp", "usr"])
-            self.expect("shell ls /", substrs=["dev", "tmp", "usr"])
+            self.expect("platform shell ls /", substrs=["dev", "tmp", "usr"], 
ordered=False)
+            self.expect("shell ls /", substrs=["dev", "tmp", "usr"], 
ordered=False)
 
     @no_debug_info_test
     def test_shell_builtin(self):

>From 959b8d3712a79a940ed25b09ac6047544a550900 Mon Sep 17 00:00:00 2001
From: Jason Molenda <[email protected]>
Date: Fri, 6 Feb 2026 22:21:44 -0800
Subject: [PATCH 2/7] Add comment about how we're forcing the scan of the
 newly-discovered shared cache in ProcessGDBRemote.

---
 lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp 
b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index eb85b9278c54b..b43ba6cabd810 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -4374,6 +4374,9 @@ StructuredData::ObjectSP 
ProcessGDBRemote::GetSharedCacheInfo() {
         uuid.SetFromStringRef(uuid_str);
         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);
       }
       m_shared_cache_info_sp = response_sp;

>From 39022e065913b254fe40ade8af8f7bd868e67da6 Mon Sep 17 00:00:00 2001
From: Jason Molenda <[email protected]>
Date: Fri, 6 Feb 2026 22:29:16 -0800
Subject: [PATCH 3/7] ws fix

---
 lldb/test/API/commands/platform/basic/TestPlatformCommand.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lldb/test/API/commands/platform/basic/TestPlatformCommand.py 
b/lldb/test/API/commands/platform/basic/TestPlatformCommand.py
index e9e1b8f9ce796..03a9c6f7a8eba 100644
--- a/lldb/test/API/commands/platform/basic/TestPlatformCommand.py
+++ b/lldb/test/API/commands/platform/basic/TestPlatformCommand.py
@@ -2,7 +2,6 @@
 Test some lldb platform commands.
 """
 
-
 import lldb
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
@@ -71,7 +70,9 @@ def test_shell(self):
             self.expect("platform shell ls /", substrs=["cache", "dev", 
"system"])
             self.expect("shell ls /", substrs=["cache", "dev", "system"])
         else:
-            self.expect("platform shell ls /", substrs=["dev", "tmp", "usr"], 
ordered=False)
+            self.expect(
+                "platform shell ls /", substrs=["dev", "tmp", "usr"], 
ordered=False
+            )
             self.expect("shell ls /", substrs=["dev", "tmp", "usr"], 
ordered=False)
 
     @no_debug_info_test

>From 939ae5c3dbf3e90b2714e153aaa177b34d8b1aa9 Mon Sep 17 00:00:00 2001
From: Jason Molenda <[email protected]>
Date: Mon, 9 Feb 2026 10:35:50 -0800
Subject: [PATCH 4/7] 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, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm 
b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index 6d1755f346df8..df0332bfeb7f1 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -696,8 +696,8 @@ bool GetImages(llvm::StringMap<SharedCacheImageInfo> 
**images, UUID &uuid) {
     return false;
   }
 
-  // Given the UUID and filepath to a shared cache on the local debug host
-  // system, open it and add all of the binary images to m_caches.
+  /// Given the UUID and filepath to a shared cache on the local debug host
+  /// system, open it and add all of the binary images to m_caches.
   bool CreateSharedCacheImageList(UUID uuid, std::string filepath);
 
   SharedCacheInfo();

>From 9415e7968ebab5ceb59e5ec4fa2428269ba21fe9 Mon Sep 17 00:00:00 2001
From: Jason Molenda <[email protected]>
Date: Mon, 9 Feb 2026 10:36:08 -0800
Subject: [PATCH 5/7] 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 df0332bfeb7f1..3da9ce2e33fc5 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -689,7 +689,7 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t 
cache,
   }
 
   bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images, UUID &uuid) {
-    if (m_caches.find(uuid) != m_caches.end()) {
+    if (m_caches.contains(uuid)) {
       *images = &m_caches[uuid];
       return true;
     }

>From 09268d108b85998873acf28e3f4a22b2d610dc20 Mon Sep 17 00:00:00 2001
From: Jason Molenda <[email protected]>
Date: Mon, 9 Feb 2026 10:47:38 -0800
Subject: [PATCH 6/7] std::map doesn't have a .contains method

Revert "Update lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm"

This reverts commit 9415e7968ebab5ceb59e5ec4fa2428269ba21fe9.
---
 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 3da9ce2e33fc5..df0332bfeb7f1 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -689,7 +689,7 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t 
cache,
   }
 
   bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images, UUID &uuid) {
-    if (m_caches.contains(uuid)) {
+    if (m_caches.find(uuid) != m_caches.end()) {
       *images = &m_caches[uuid];
       return true;
     }

>From 01e7f3756ea01664cfb8a6edd70cfb2b5553427f Mon Sep 17 00:00:00 2001
From: Jason Molenda <[email protected]>
Date: Mon, 9 Feb 2026 12:48:26 -0800
Subject: [PATCH 7/7] Address Jonas' review feedback. Add a non-verbose log
 message when we map binaries in to lldb's address space, for some light
 indication of when the new method is being used.

---
 lldb/include/lldb/Host/HostInfoBase.h            |  2 +-
 lldb/include/lldb/Host/macosx/HostInfoMacOSX.h   |  2 +-
 lldb/include/lldb/Target/DynamicLoader.h         |  1 +
 lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm | 13 +++++++++----
 4 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/lldb/include/lldb/Host/HostInfoBase.h 
b/lldb/include/lldb/Host/HostInfoBase.h
index fc9ab96676341..bc80e5e62ed39 100644
--- a/lldb/include/lldb/Host/HostInfoBase.h
+++ b/lldb/include/lldb/Host/HostInfoBase.h
@@ -194,7 +194,7 @@ class HostInfoBase {
   /// 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, UUID &uuid) {
+  GetSharedCacheImageInfo(llvm::StringRef image_name, const UUID &uuid) {
     return {};
   }
 
diff --git a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h 
b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
index 78f8344aefd13..c58056cb492b7 100644
--- a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
+++ b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
@@ -46,7 +46,7 @@ class HostInfoMacOSX : public HostInfoPosix {
   GetSharedCacheImageInfo(llvm::StringRef image_name);
 
   static SharedCacheImageInfo
-  GetSharedCacheImageInfo(llvm::StringRef image_name, UUID &uuid);
+  GetSharedCacheImageInfo(llvm::StringRef image_name, const UUID &uuid);
 
   static bool SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid);
 
diff --git a/lldb/include/lldb/Target/DynamicLoader.h 
b/lldb/include/lldb/Target/DynamicLoader.h
index 04fd7556e1068..d1d832f759748 100644
--- a/lldb/include/lldb/Target/DynamicLoader.h
+++ b/lldb/include/lldb/Target/DynamicLoader.h
@@ -326,6 +326,7 @@ class DynamicLoader : public PluginInterface {
     uuid.Clear();
     using_shared_cache = eLazyBoolCalculate;
     private_shared_cache = eLazyBoolCalculate;
+    shared_cache_path.Clear();
     return false;
   }
 
diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm 
b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index df0332bfeb7f1..d37062b152a00 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -688,11 +688,13 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t 
cache,
     return m_caches[m_host_uuid];
   }
 
-  bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images, UUID &uuid) {
+  bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images,
+                 const UUID &uuid) {
     if (m_caches.find(uuid) != m_caches.end()) {
       *images = &m_caches[uuid];
       return true;
     }
+    *images = nullptr;
     return false;
   }
 
@@ -792,6 +794,10 @@ static dispatch_data_t 
(*g_dyld_image_segment_data_4HWTrace)(
     return {};
 
   Log *log = GetLog(LLDBLog::Modules);
+  LLDB_LOGF(log,
+            "map_shared_cache_binary_segments() mapping segments of "
+            "dyld_image_t %p into lldb address space",
+            image);
   bool log_verbosely = log && log->GetVerbose();
   for (const segment &seg : segments) {
     if (log_verbosely)
@@ -979,12 +985,11 @@ static dispatch_data_t 
(*g_dyld_image_segment_data_4HWTrace)(
 
 SharedCacheImageInfo
 HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name,
-                                        UUID &uuid) {
+                                        const UUID &uuid) {
   llvm::StringMap<SharedCacheImageInfo> *shared_cache_info;
   if (GetSharedCacheSingleton().GetImages(&shared_cache_info, uuid))
     return shared_cache_info->lookup(image_name);
-  else
-    return {};
+  return {};
 }
 
 bool HostInfoMacOSX::SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid) {

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to