Author: Jonas Devlieghere
Date: 2026-06-26T08:54:09-07:00
New Revision: 6a5fe4bf112d2d60f7e03a233d486ff502ce1b8c

URL: 
https://github.com/llvm/llvm-project/commit/6a5fe4bf112d2d60f7e03a233d486ff502ce1b8c
DIFF: 
https://github.com/llvm/llvm-project/commit/6a5fe4bf112d2d60f7e03a233d486ff502ce1b8c.diff

LOG: [lldb] Confine host shared cache reads to mapped segments (#205454)

When reading shared cache libraries out of lldb's own memory (the
default, eSymbolSharedCacheUseHostAndInferiorSharedCache), the dyld
introspection path built a plain DataExtractor spanning an image's
[minVmAddr, maxVmAddr). A shared cache image's segments may not be
contiguous: other images' data and unmapped guard pages may lie between
them.

Take advantage of the VirtualDataExtractor with a per-segment lookup
table instead, matching the map_shared_cache_binary_segments path, so
reads are confined to mapped segments.

Added: 
    lldb/test/API/macosx/shared-cache-host-memory/Makefile
    lldb/test/API/macosx/shared-cache-host-memory/TestSharedCacheHostMemory.py
    lldb/test/API/macosx/shared-cache-host-memory/main.c

Modified: 
    lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm

Removed: 
    


################################################################################
diff  --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm 
b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index 75a584d90121a..69f8bbdce91f6 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -32,6 +32,8 @@
 // C++ Includes
 #include <optional>
 #include <string>
+#include <utility>
+#include <vector>
 
 // C inclues
 #include <cstdlib>
@@ -1023,6 +1025,10 @@ static DataExtractorSP 
map_shared_cache_binary_segments(void *image) {
     __block uint64_t maxVmAddr = 0;
     uuid_t uuidStore;
     __block uuid_t *uuid = &uuidStore;
+    // A shared cache image's segments can occupy non-adjacent regions of the
+    // cache. Keep track of the segment's start and end so we can build a
+    // VirtualDataExtractor that prevents reads between segments.
+    __block std::vector<std::pair<uint64_t, uint64_t>> segments;
 
     dyld_image_for_each_segment_info(
         image,
@@ -1030,12 +1036,22 @@ static DataExtractorSP 
map_shared_cache_binary_segments(void *image) {
           minVmAddr = std::min(minVmAddr, vmAddr);
           maxVmAddr = std::max(maxVmAddr, vmAddr + vmSize);
           dyld_image_copy_uuid(image, uuid);
+          if (vmSize > 0)
+            segments.emplace_back(vmAddr, vmSize);
         });
     assert(minVmAddr != UINT_MAX);
     assert(maxVmAddr != 0);
     lldb::DataBufferSP data_sp = std::make_shared<DataBufferUnowned>(
         (uint8_t *)minVmAddr, maxVmAddr - minVmAddr);
-    lldb::DataExtractorSP extractor_sp = 
std::make_shared<DataExtractor>(data_sp);
+    // Data is read in place from lldb's own shared cache, so each segment's
+    // virtual offset (image base at 0) equals its physical offset in the
+    // buffer.
+    VirtualDataExtractor::LookupTable table;
+    for (const std::pair<uint64_t, uint64_t> &seg : segments)
+      table.Append(VirtualDataExtractor::LookupTable::Entry(
+          seg.first - minVmAddr, seg.second, seg.first - minVmAddr));
+    lldb::DataExtractorSP extractor_sp =
+        std::make_shared<VirtualDataExtractor>(data_sp, table);
     // Copy the filename into the const string pool to
     // ensure lifetime.
     ConstString installname(dyld_image_get_installname(image));

diff  --git a/lldb/test/API/macosx/shared-cache-host-memory/Makefile 
b/lldb/test/API/macosx/shared-cache-host-memory/Makefile
new file mode 100644
index 0000000000000..4774d1d781b3c
--- /dev/null
+++ b/lldb/test/API/macosx/shared-cache-host-memory/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+MAKE_DSYM := NO
+
+include Makefile.rules

diff  --git 
a/lldb/test/API/macosx/shared-cache-host-memory/TestSharedCacheHostMemory.py 
b/lldb/test/API/macosx/shared-cache-host-memory/TestSharedCacheHostMemory.py
new file mode 100644
index 0000000000000..f45bf89b99444
--- /dev/null
+++ b/lldb/test/API/macosx/shared-cache-host-memory/TestSharedCacheHostMemory.py
@@ -0,0 +1,48 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class SharedCacheHostMemoryTestCase(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    @skipUnlessDarwin
+    @skipIfRemote
+    def test_host_lldb_memory(self):
+        """Stop in a shared cache binary loaded from lldb's own memory and
+        backtrace through it."""
+        self.build()
+
+        self.runCmd("settings set symbols.shared-cache-binary-loading 
host-lldb-memory")
+        self.addTearDownHook(
+            lambda: self.runCmd("settings clear 
symbols.shared-cache-binary-loading")
+        )
+
+        target = self.createTestTarget()
+
+        # Breaking on puts forces lldb to load and symbolicate the shared cache
+        # binary it lives in. The breakpoint resolves once that library is
+        # loaded as the process launches.
+        breakpoint = target.BreakpointCreateByName("puts")
+
+        process = target.LaunchSimple(None, None, 
self.get_process_working_directory())
+        self.assertState(process.GetState(), lldb.eStateStopped, 
PROCESS_STOPPED)
+        self.assertGreater(
+            breakpoint.GetNumLocations(),
+            0,
+            "puts breakpoint should resolve in the shared cache binary",
+        )
+
+        thread = lldbutil.get_stopped_thread(process, 
lldb.eStopReasonBreakpoint)
+        self.assertIsNotNone(thread, "Expected to stop at the puts breakpoint")
+
+        # We should be able to walk the stack out of the shared cache binary
+        # and back to main without crashing.
+        self.assertEqual(thread.GetFrameAtIndex(0).GetFunctionName(), "puts")
+        self.assertGreater(thread.GetNumFrames(), 1)
+        frame_names = [
+            thread.GetFrameAtIndex(i).GetFunctionName()
+            for i in range(thread.GetNumFrames())
+        ]
+        self.assertIn("main", frame_names)

diff  --git a/lldb/test/API/macosx/shared-cache-host-memory/main.c 
b/lldb/test/API/macosx/shared-cache-host-memory/main.c
new file mode 100644
index 0000000000000..9d2a89dc43140
--- /dev/null
+++ b/lldb/test/API/macosx/shared-cache-host-memory/main.c
@@ -0,0 +1,4 @@
+#include <stdio.h>
+int main() {
+  puts("HI"); // break here
+}


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

Reply via email to