[Lldb-commits] [lldb] [lldb][PlatformDarwin] Make PlatformDarwin define a safe-path for auto-loading scripting resources (PR #191454)

via lldb-commits lldb-commits at lists.llvm.org
Fri Apr 10 09:21:19 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)

<details>
<summary>Changes</summary>

This patch adds a new API (`Platform::GetSafeAutoLoadPaths`) which gives platforms a chance to advertise their safe-paths. We have a `LLDB_SAFE_AUTO_LOAD_PATHS` CMake variable for this that vendors can set, but for sensible defaults we wanted to bake them into LLDB for convenience. We could set the defaults of the CMake variable per-platform, but for Apple platforms that's trickier because the path isn't statically known (it's the SDK path derived from the target's triple).

Depends on:
* https://github.com/llvm/llvm-project/pull/191446

Assisted-by: Claude
- Used Claude to write the skeleton of the test before manually cleaning it up.

---
Full diff: https://github.com/llvm/llvm-project/pull/191454.diff


11 Files Affected:

- (modified) lldb/include/lldb/Core/Debugger.h (+1-1) 
- (modified) lldb/include/lldb/Target/Platform.h (+4) 
- (modified) lldb/include/lldb/Utility/FileSpecList.h (+4) 
- (modified) lldb/source/Core/Debugger.cpp (+13) 
- (modified) lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm (+1) 
- (modified) lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (+32) 
- (modified) lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h (+2) 
- (modified) lldb/source/Target/Platform.cpp (+1-1) 
- (modified) lldb/unittests/Platform/CMakeLists.txt (+1) 
- (modified) lldb/unittests/Platform/PlatformDarwinTest.cpp (+16) 
- (modified) lldb/unittests/Utility/FileSpecListTest.cpp (+52) 


``````````diff
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index fa4483c93e639..14bd27423413f 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -149,7 +149,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
   /// scripting resources from. Currently whether to load scripts
   /// unconditionally is controlled via the
   /// `target.load-script-from-symbol-file` setting.
-  static FileSpecList GetSafeAutoLoadPaths();
+  FileSpecList GetSafeAutoLoadPaths();
 
   void Clear();
 
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 001ff7e112909..920684855681f 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -1009,6 +1009,10 @@ class Platform : public PluginInterface {
 
   LocateModuleCallback GetLocateModuleCallback() const;
 
+  /// Returns a \c FileSpecList of safe paths to auto-load scripting resources
+  /// from for a particular platform.
+  virtual llvm::Expected<FileSpecList> GetSafeAutoLoadPaths(const Target &target) { return FileSpecList(); }
+
 protected:
   /// Create a list of ArchSpecs with the given OS and a architectures. The
   /// vendor field is left as an "unspecified unknown".
diff --git a/lldb/include/lldb/Utility/FileSpecList.h b/lldb/include/lldb/Utility/FileSpecList.h
index 69c5b49841a12..ff2db60e21598 100644
--- a/lldb/include/lldb/Utility/FileSpecList.h
+++ b/lldb/include/lldb/Utility/FileSpecList.h
@@ -132,6 +132,10 @@ class FileSpecList {
   ///     A new file to append to this file list.
   void Append(const FileSpec &file);
 
+  void Append(const FileSpecList &other) {
+    m_files.insert(end(), std::begin(other), std::end(other));
+  }
+
   /// Append a FileSpec object if unique.
   ///
   /// Appends \a file to the end of the file list if it doesn't already exist
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 9deef5a4ae503..f91410ab16115 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -2596,6 +2596,19 @@ StructuredData::DictionarySP Debugger::GetBuildConfiguration() {
 FileSpecList Debugger::GetSafeAutoLoadPaths() {
   FileSpecList fspecs = GetDefaultSafeAutoLoadPaths();
 
+  // Add platform-specific safe-paths.
+  if (TargetSP target_sp = GetSelectedTarget()) {
+    if (PlatformSP platform_sp = GetPlatformList().GetSelectedPlatform()) {
+      if (auto platform_fspecs_or_err = platform_sp->GetSafeAutoLoadPaths(*target_sp))
+        fspecs.Append(*platform_fspecs_or_err);
+      else
+        LLDB_LOG_ERROR(
+            GetLog(LLDBLog::Modules | LLDBLog::Platform), platform_fspecs_or_err.takeError(),
+            "Skipping safe auto-load path: {0}");
+    }
+  }
+
+  // Properties for testing get added last so they take priority.
 #ifndef NDEBUG
   for (const auto &fspec :
        TestingProperties::GetGlobalTestingProperties().GetSafeAutoLoadPaths())
diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index 2214678d392b5..9f1335ee2946d 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -14,6 +14,7 @@
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/DataBuffer.h"
 #include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/FileSpecList.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Timer.h"
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 6d6aa68a2462f..fdbc6ce4ef777 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -1563,3 +1563,35 @@ PlatformDarwin::ResolveSDKPathFromDebugInfo(CompileUnit &unit) {
 
   return path_or_err->str();
 }
+
+llvm::Expected<FileSpecList> PlatformDarwin::GetSafeAutoLoadPaths(const Target &target) {
+  Log *log = GetLog(LLDBLog::Modules | LLDBLog::Platform);
+
+  XcodeSDK::Type sdk_type =
+      XcodeSDK::GetSDKTypeForTriple(target.GetArchitecture().GetTriple());
+  XcodeSDK sdk(XcodeSDK::Info{sdk_type, {}});
+
+  auto sdk_root_or_err = HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk});
+  if (!sdk_root_or_err) {
+    LLDB_LOG_ERROR(log, sdk_root_or_err.takeError(),
+                   "Failed to resolve SDK root for triple '{1}': {0}",
+                   target.GetArchitecture().GetTriple().str());
+
+    // Fall back to any macOS SDK.
+    sdk = XcodeSDK::GetAnyMacOS();
+    LLDB_LOG(log, "Falling back to SDK '{0}'", sdk.GetString());
+    sdk_root_or_err = HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk});
+  }
+
+  if (!sdk_root_or_err)
+    return sdk_root_or_err.takeError();
+
+  // $SDKROOT/usr/share/lldb is an auto-loadable path.
+  llvm::SmallString<256> resolved(*sdk_root_or_err);
+  llvm::sys::path::append(resolved, "usr", "share", "lldb");
+
+  FileSpecList fspecs;
+  fspecs.Append(FileSpec(resolved));
+
+  return fspecs;
+}
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index fd5207e82b6db..9e446d65ea29a 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -159,6 +159,8 @@ class PlatformDarwin : public PlatformPOSIX {
                                              const Target &target,
                                              const FileSpec &symfile_spec);
 
+  llvm::Expected<FileSpecList> GetSafeAutoLoadPaths(const Target &target) override;
+
 protected:
   static const char *GetCompatibleArch(ArchSpec::Core core, size_t idx);
 
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index c92a71d2c3baa..2cda5aeb1c697 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -190,7 +190,7 @@ Platform::LocateExecutableScriptingResourcesFromSafePaths(
           ->GetSanitizedScriptingModuleName(
               module_spec.GetFileNameStrippingExtension().GetStringRef());
 
-  FileSpecList paths = Debugger::GetSafeAutoLoadPaths();
+  FileSpecList paths = target.GetDebugger().GetSafeAutoLoadPaths();
 
   // Iterate in reverse so we consider the latest appended path first.
   for (FileSpec path : llvm::reverse(paths)) {
diff --git a/lldb/unittests/Platform/CMakeLists.txt b/lldb/unittests/Platform/CMakeLists.txt
index f8755432bf6d7..b3c87b33527bd 100644
--- a/lldb/unittests/Platform/CMakeLists.txt
+++ b/lldb/unittests/Platform/CMakeLists.txt
@@ -14,6 +14,7 @@ add_lldb_unittest(LLDBPlatformTests
     lldbPluginPlatformMacOSX
     lldbPluginPlatformNetBSD
     lldbUtilityHelpers
+    LLVMTestingSupport
   )
 
 add_subdirectory(Android)
diff --git a/lldb/unittests/Platform/PlatformDarwinTest.cpp b/lldb/unittests/Platform/PlatformDarwinTest.cpp
index 2f9c41c93e90e..e79986b426d46 100644
--- a/lldb/unittests/Platform/PlatformDarwinTest.cpp
+++ b/lldb/unittests/Platform/PlatformDarwinTest.cpp
@@ -22,6 +22,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FormatVariadic.h"
+#include "llvm/Testing/Support/Error.h"
 
 #include <memory>
 #include <tuple>
@@ -718,3 +719,18 @@ INSTANTIATE_TEST_SUITE_P(PlatformDarwinLocateWithSpecialCharsTest,
                          PlatformDarwinLocateWithSpecialCharsTestFixture,
                          testing::ValuesIn(std::vector<SpecialCharTestCase>{
                              {' ', '_'}, {'.', '_'}, {'-', '_'}, {'+', 'x'}}));
+
+TEST_F(PlatformDarwinLocateTest, GetSafeAutoLoadPaths) {
+  // Tests PlatformDarwin::GetSafeAutoLoadPaths returns a path into the SDK on Darwin platforms.
+
+  auto paths_or_err = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)->GetSafeAutoLoadPaths(*m_target_sp);
+
+  ASSERT_THAT_EXPECTED(paths_or_err, llvm::Succeeded());
+
+  ASSERT_EQ(paths_or_err->GetSize(), 1u);
+
+  // The returned path should be $SDKROOT/usr/share/lldb.
+  FileSpec path = paths_or_err->GetFileSpecAtIndex(0);
+  EXPECT_TRUE(llvm::StringRef(path.GetPath()).ends_with("/usr/share/lldb"))
+      << "Unexpected path: " << path.GetPath();
+}
diff --git a/lldb/unittests/Utility/FileSpecListTest.cpp b/lldb/unittests/Utility/FileSpecListTest.cpp
index d3f89ad0dfcb3..4a09d48a47fb3 100644
--- a/lldb/unittests/Utility/FileSpecListTest.cpp
+++ b/lldb/unittests/Utility/FileSpecListTest.cpp
@@ -301,6 +301,58 @@ TEST(SupportFileListTest, DifferentBasename) {
   EXPECT_EQ(ret, UINT32_MAX);
 }
 
+TEST(FileSpecListTest, AppendFileSpecList) {
+  // Test appending a FileSpecList to an existing FileSpecList.
+
+  FileSpecList list_a;
+  list_a.Append(PosixSpec("/a/foo.h"));
+  list_a.Append(PosixSpec("/a/bar.h"));
+
+  FileSpecList list_b;
+  list_b.Append(PosixSpec("/b/baz.h"));
+  list_b.Append(PosixSpec("/b/qux.h"));
+
+  // Duplicate gets appended too.
+  list_b.Append(PosixSpec("/a/foo.h"));
+
+  list_a.Append(list_b);
+  ASSERT_EQ(list_a.GetSize(), 5u);
+  EXPECT_EQ(list_a.GetFileSpecAtIndex(0), PosixSpec("/a/foo.h"));
+  EXPECT_EQ(list_a.GetFileSpecAtIndex(1), PosixSpec("/a/bar.h"));
+  EXPECT_EQ(list_a.GetFileSpecAtIndex(2), PosixSpec("/b/baz.h"));
+  EXPECT_EQ(list_a.GetFileSpecAtIndex(3), PosixSpec("/b/qux.h"));
+  EXPECT_EQ(list_a.GetFileSpecAtIndex(4), PosixSpec("/a/foo.h"));
+}
+
+TEST(FileSpecListTest, AppendEmptyFileSpecList) {
+  // Test appending an empty FileSpecList to an existing FileSpecList.
+
+  FileSpecList list_a;
+  list_a.Append(PosixSpec("/a/foo.h"));
+
+  FileSpecList empty;
+  list_a.Append(empty);
+
+  ASSERT_EQ(list_a.GetSize(), 1u);
+  EXPECT_EQ(list_a.GetFileSpecAtIndex(0), PosixSpec("/a/foo.h"));
+}
+
+TEST(FileSpecListTest, AppendToEmptyFileSpecList) {
+  // Test appending to an empty FileSpecList to an existing FileSpecList.
+
+  FileSpecList list_a;
+  FileSpecList list_b;
+  list_b.Append(list_a);
+
+  ASSERT_EQ(list_b.GetSize(), 0u);
+
+  list_a.Append(PosixSpec("/a/foo.h"));
+  list_b.Append(list_a);
+
+  ASSERT_EQ(list_b.GetSize(), 1u);
+  EXPECT_EQ(list_b.GetFileSpecAtIndex(0), PosixSpec("/a/foo.h"));
+}
+
 // No prefixes are configured.
 // The support file and the breakpoint file are different.
 // Should find it incompatible.

``````````

</details>


https://github.com/llvm/llvm-project/pull/191454


More information about the lldb-commits mailing list