[Lldb-commits] [lldb] [lldb] Add setting to specify (by name) which module's scripting resources can be auto-loaded (PR #188722)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Tue Mar 31 08:59:43 PDT 2026
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/188722
>From 1038197777097d615cac3bd11ed3c9f83a041710 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 31 Mar 2026 11:59:22 +0200
Subject: [PATCH 1/7] [lldb][Platform] Handle LoadScriptFromSymFile per-module
FileSpec
This patch changes the `Platform::LocateXXX` to return a map from `FileSpec` to `LoadScriptFromSymFile` enum.
This is needed for https://github.com/llvm/llvm-project/pull/188722, where I intend to set `LoadScriptFromSymFile` per-module.
By default the `Platform::LocateXXX` set the value to whatever the target's current `target.load-script-from-symbol-file` is set to. In https://github.com/llvm/llvm-project/pull/188722 we'll allow overriding this per-target setting on a per-module basis.
Drive-by:
* Added logging when we fail to load a script.
---
lldb/include/lldb/Target/Platform.h | 18 ++-
lldb/source/Core/Module.cpp | 21 +--
.../Platform/MacOSX/PlatformDarwin.cpp | 26 +--
.../Plugins/Platform/MacOSX/PlatformDarwin.h | 11 +-
lldb/source/Target/Platform.cpp | 30 ++--
.../unittests/Platform/PlatformDarwinTest.cpp | 153 ++++++++----------
lldb/unittests/Platform/PlatformTest.cpp | 137 ++++++++--------
7 files changed, 196 insertions(+), 200 deletions(-)
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 3d0776d95b539..6bdaf10ef0713 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -273,15 +273,15 @@ class Platform : public PluginInterface {
/// Locate the scripting resource given a module specification.
///
- /// Locating the file should happen only on the local computer or using the
- /// current computers global settings.
- FileSpecList LocateExecutableScriptingResources(Target *target,
- Module &module,
- Stream &feedback_stream);
+ /// Returns a map from a located script's \c FileSpec to the
+ /// \c LoadScriptFromSymFile with which LLDB should load it.
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+ LocateExecutableScriptingResources(Target *target, Module &module,
+ Stream &feedback_stream);
/// Locate the platform-specific scripting resource given a module
/// specification.
- virtual FileSpecList
+ virtual llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
LocateExecutableScriptingResourcesForPlatform(Target *target, Module &module,
Stream &feedback_stream);
@@ -291,8 +291,10 @@ class Platform : public PluginInterface {
///
/// E.g., for Python it will look for a script at:
/// \c <safe-path>/<module-name>/<module-name>.py
- static FileSpecList LocateExecutableScriptingResourcesFromSafePaths(
- Stream &feedback_stream, FileSpec module_spec, const Target &target);
+ static llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+ LocateExecutableScriptingResourcesFromSafePaths(Stream &feedback_stream,
+ FileSpec module_spec,
+ const Target &target);
/// \param[in] module_spec
/// The ModuleSpec of a binary to find.
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 3d33a5011fb5e..455d50c965d72 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1439,12 +1439,6 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error) {
return false;
}
- LoadScriptFromSymFile should_load =
- target->TargetProperties::GetLoadScriptFromSymbolFile();
-
- if (should_load == eLoadScriptFromSymFileFalse)
- return false;
-
Debugger &debugger = target->GetDebugger();
const ScriptLanguage script_language = debugger.GetScriptLanguage();
if (script_language == eScriptLanguageNone)
@@ -1464,22 +1458,21 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error) {
}
StreamString feedback_stream;
- FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources(
- target, *this, feedback_stream);
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> file_specs =
+ platform_sp->LocateExecutableScriptingResources(target, *this,
+ feedback_stream);
if (!feedback_stream.Empty())
debugger.ReportWarning(feedback_stream.GetString().str(), debugger.GetID());
- const uint32_t num_specs = file_specs.GetSize();
- if (num_specs == 0)
- return true;
+ for (const auto &[scripting_fspec, load_style] : file_specs) {
+ if (load_style == eLoadScriptFromSymFileFalse)
+ continue;
- for (uint32_t i = 0; i < num_specs; ++i) {
- FileSpec scripting_fspec(file_specs.GetFileSpecAtIndex(i));
if (!FileSystem::Instance().Exists(scripting_fspec))
continue;
- if (should_load == eLoadScriptFromSymFileWarn) {
+ if (load_style == eLoadScriptFromSymFileWarn) {
// clang-format off
debugger.ReportWarning(
llvm::formatv(
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 98f0025303ac1..c6351b02791db 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -196,7 +196,8 @@ PlatformDarwin::PutFile(const lldb_private::FileSpec &source,
return PlatformPOSIX::PutFile(source, destination, uid, gid);
}
-FileSpecList PlatformDarwin::LocateExecutableScriptingResourcesFromDSYM(
+llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+PlatformDarwin::LocateExecutableScriptingResourcesFromDSYM(
Stream &feedback_stream, FileSpec module_spec, const Target &target,
const FileSpec &symfile_spec) {
@@ -204,7 +205,7 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResourcesFromDSYM(
"Trying to locate scripting resources but no ScriptInterpreter is "
"available.");
- FileSpecList file_list;
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> file_specs;
while (module_spec.GetFilename()) {
ScriptInterpreter::SanitizedScriptingModuleName sanitized_name =
target.GetDebugger()
@@ -234,7 +235,8 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResourcesFromDSYM(
orig_script_fspec, script_fspec);
if (FileSystem::Instance().Exists(script_fspec)) {
- file_list.Append(script_fspec);
+ file_specs.try_emplace(std::move(script_fspec),
+ target.GetLoadScriptFromSymbolFile());
break;
}
@@ -248,17 +250,19 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResourcesFromDSYM(
module_spec.SetFilename(filename_no_extension);
}
- return file_list;
+ return file_specs;
}
-FileSpecList PlatformDarwin::LocateExecutableScriptingResourcesForPlatform(
+llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+PlatformDarwin::LocateExecutableScriptingResourcesForPlatform(
Target *target, Module &module, Stream &feedback_stream) {
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> file_specs;
if (!target)
- return {};
+ return file_specs;
// For now only Python scripts supported for auto-loading.
if (target->GetDebugger().GetScriptLanguage() != eScriptLanguagePython)
- return {};
+ return file_specs;
// NB some extensions might be meaningful and should not be stripped -
// "this.binary.file"
@@ -270,15 +274,15 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResourcesForPlatform(
const FileSpec &module_spec = module.GetFileSpec();
if (!module_spec)
- return {};
+ return file_specs;
SymbolFile *symfile = module.GetSymbolFile();
if (!symfile)
- return {};
+ return file_specs;
ObjectFile *objfile = symfile->GetObjectFile();
if (!objfile)
- return {};
+ return file_specs;
const FileSpec &symfile_spec = objfile->GetFileSpec();
if (symfile_spec &&
@@ -288,7 +292,7 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResourcesForPlatform(
return LocateExecutableScriptingResourcesFromDSYM(
feedback_stream, module_spec, *target, symfile_spec);
- return {};
+ return file_specs;
}
Status PlatformDarwin::ResolveSymbolFile(Target &target,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index 2b0b7ad4b827d..3c98d420dde8c 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -67,7 +67,8 @@ class PlatformDarwin : public PlatformPOSIX {
Status ResolveSymbolFile(Target &target, const ModuleSpec &sym_spec,
FileSpec &sym_file) override;
- FileSpecList LocateExecutableScriptingResourcesForPlatform(
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+ LocateExecutableScriptingResourcesForPlatform(
Target *target, Module &module_spec, Stream &feedback_stream) override;
Status GetSharedModule(const ModuleSpec &module_spec, Process *process,
@@ -150,9 +151,11 @@ class PlatformDarwin : public PlatformPOSIX {
/// Resources directory in the same dSYM.
/// E.g., \c /path/to/.dSYM/Contents/Resources/DWARF/a.out
///
- static FileSpecList LocateExecutableScriptingResourcesFromDSYM(
- Stream &feedback_stream, FileSpec module_spec, const Target &target,
- const FileSpec &symfile_spec);
+ static llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+ LocateExecutableScriptingResourcesFromDSYM(Stream &feedback_stream,
+ FileSpec module_spec,
+ const Target &target,
+ const FileSpec &symfile_spec);
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 51ef8d7259d9a..a676c50ef77ed 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -157,14 +157,17 @@ Status Platform::GetFileWithUUID(const FileSpec &platform_file,
return Status();
}
-FileSpecList Platform::LocateExecutableScriptingResourcesFromSafePaths(
+llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+Platform::LocateExecutableScriptingResourcesFromSafePaths(
Stream &feedback_stream, FileSpec module_spec, const Target &target) {
assert(module_spec);
assert(target.GetDebugger().GetScriptInterpreter());
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> file_specs;
+
// For now only Python scripts supported for auto-loading.
if (target.GetDebugger().GetScriptLanguage() != eScriptLanguagePython)
- return {};
+ return file_specs;
ScriptInterpreter::SanitizedScriptingModuleName sanitized_name =
target.GetDebugger()
@@ -172,7 +175,6 @@ FileSpecList Platform::LocateExecutableScriptingResourcesFromSafePaths(
->GetSanitizedScriptingModuleName(
module_spec.GetFileNameStrippingExtension().GetStringRef());
- FileSpecList file_list;
FileSpecList paths = Debugger::GetSafeAutoLoadPaths();
// Iterate in reverse so we consider the latest appended path first.
@@ -197,36 +199,40 @@ FileSpecList Platform::LocateExecutableScriptingResourcesFromSafePaths(
orig_script_fspec, script_fspec);
if (FileSystem::Instance().Exists(script_fspec))
- file_list.Append(script_fspec);
+ file_specs.try_emplace(std::move(script_fspec),
+ target.GetLoadScriptFromSymbolFile());
// If we successfully found a directory in a safe auto-load path
// stop looking at any other paths.
break;
}
- return file_list;
+ return file_specs;
}
-FileSpecList Platform::LocateExecutableScriptingResourcesForPlatform(
+llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+Platform::LocateExecutableScriptingResourcesForPlatform(
Target *target, Module &module, Stream &feedback_stream) {
- return {};
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> empty;
+ return empty;
}
-FileSpecList
+llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
Platform::LocateExecutableScriptingResources(Target *target, Module &module,
Stream &feedback_stream) {
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> empty;
if (!target)
- return {};
+ return empty;
// Give derived platforms a chance to locate scripting resources.
- if (FileSpecList fspecs = LocateExecutableScriptingResourcesForPlatform(
+ if (auto fspecs = LocateExecutableScriptingResourcesForPlatform(
target, module, feedback_stream);
- !fspecs.IsEmpty())
+ !fspecs.empty())
return fspecs;
const FileSpec &module_spec = module.GetFileSpec();
if (!module_spec)
- return {};
+ return empty;
return LocateExecutableScriptingResourcesFromSafePaths(feedback_stream,
module_spec, *target);
diff --git a/lldb/unittests/Platform/PlatformDarwinTest.cpp b/lldb/unittests/Platform/PlatformDarwinTest.cpp
index 448dcab7070df..70986bf3e0199 100644
--- a/lldb/unittests/Platform/PlatformDarwinTest.cpp
+++ b/lldb/unittests/Platform/PlatformDarwinTest.cpp
@@ -145,12 +145,11 @@ TEST_F(PlatformDarwinLocateTest,
CreateFile("TestModule.sh", m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 1u);
- EXPECT_EQ(fspecs.GetFileSpecAtIndex(0).GetFilename(), "TestModule.py");
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 1u);
+ EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "TestModule.py");
}
TEST_F(PlatformDarwinLocateTest,
@@ -171,12 +170,11 @@ TEST_F(PlatformDarwinLocateTest,
CreateFile("TestModule.sh", m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 1u);
- EXPECT_EQ(fspecs.GetFileSpecAtIndex(0).GetFilename(), "TestModule.py");
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 1u);
+ EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "TestModule.py");
}
TEST_F(PlatformDarwinLocateTest,
@@ -197,11 +195,10 @@ TEST_F(PlatformDarwinLocateTest,
CreateFile("TestModule.1.py", m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 0u);
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 0u);
}
TEST_F(PlatformDarwinLocateTest,
@@ -228,11 +225,10 @@ TEST_F(PlatformDarwinLocateTest,
CreateFile("TestModule.py", nested_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 0u);
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 0u);
}
TEST_F(
@@ -256,12 +252,11 @@ TEST_F(
CreateFile("TestModule_import.py", m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 1u);
- EXPECT_EQ(fspecs.GetFileSpecAtIndex(0).GetFilename(), "TestModule_import.py");
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 1u);
+ EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "TestModule_import.py");
EXPECT_TRUE(ss.Empty());
}
@@ -285,11 +280,10 @@ TEST_F(PlatformDarwinLocateTest,
ASSERT_TRUE(script_fspec);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 0u);
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 0u);
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because 'import.py' "
@@ -321,12 +315,11 @@ TEST_F(PlatformDarwinLocateTest,
ASSERT_TRUE(orig_fspec);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 1u);
- EXPECT_EQ(fspecs.GetFileSpecAtIndex(0).GetFilename(), "_import.py");
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 1u);
+ EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "_import.py");
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because 'import.py' "
@@ -356,12 +349,11 @@ TEST_F(
CreateFile("_import.py", m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 1u);
- EXPECT_EQ(fspecs.GetFileSpecAtIndex(0).GetFilename(), "_import.py");
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 1u);
+ EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "_import.py");
EXPECT_TRUE(ss.GetString().empty());
}
@@ -386,11 +378,10 @@ TEST_F(
ASSERT_TRUE(script_fspec);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 0u);
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 0u);
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because 'TestModule-1.1 1.py' "
@@ -423,12 +414,11 @@ TEST_F(
CreateFile("TestModule_1_1_1.py", m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 1u);
- EXPECT_EQ(fspecs.GetFileSpecAtIndex(0).GetFilename(), "TestModule_1_1_1.py");
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 1u);
+ EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "TestModule_1_1_1.py");
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because"
@@ -458,12 +448,11 @@ TEST_F(
CreateFile("TestModule_1_1_1.py", m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 1u);
- EXPECT_EQ(fspecs.GetFileSpecAtIndex(0).GetFilename(), "TestModule_1_1_1.py");
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 1u);
+ EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "TestModule_1_1_1.py");
EXPECT_TRUE(ss.GetString().empty());
}
@@ -487,11 +476,10 @@ TEST_F(
CreateFile("mykeyword-1.1 1.py", m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 0u);
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 0u);
EXPECT_TRUE(
ss.GetString().contains("conflicts with the keyword 'mykeyword_1_1_1'"));
}
@@ -518,12 +506,11 @@ TEST_F(
CreateFile("_mykeyword_1_1_1.py", m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 1u);
- EXPECT_EQ(fspecs.GetFileSpecAtIndex(0).GetFilename(), "_mykeyword_1_1_1.py");
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 1u);
+ EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "_mykeyword_1_1_1.py");
EXPECT_TRUE(ss.GetString().contains("Ignoring 'mykeyword-1.1 1.py' and "
"loading '_mykeyword_1_1_1.py' instead"));
}
@@ -550,12 +537,11 @@ TEST_F(
CreateFile("_mykeyword_1_1_1.py", m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 1u);
- EXPECT_EQ(fspecs.GetFileSpecAtIndex(0).GetFilename(), "_mykeyword_1_1_1.py");
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 1u);
+ EXPECT_EQ(fspecs.begin()->getFirst().GetFilename(), "_mykeyword_1_1_1.py");
EXPECT_TRUE(ss.Empty());
}
@@ -591,11 +577,10 @@ TEST_P(PlatformDarwinLocateWithSpecialCharsTestFixture,
CreateFile(script_name, m_tmp_dsym_python_dir);
StreamString ss;
- FileSpecList fspecs =
- std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
- ->LocateExecutableScriptingResourcesFromDSYM(
- ss, module_fspec, *m_target_sp, dsym_module_fpec);
- EXPECT_EQ(fspecs.GetSize(), 0u);
+ auto fspecs = std::static_pointer_cast<PlatformDarwin>(m_platform_sp)
+ ->LocateExecutableScriptingResourcesFromDSYM(
+ ss, module_fspec, *m_target_sp, dsym_module_fpec);
+ EXPECT_EQ(fspecs.size(), 0u);
std::string expected =
llvm::formatv("please rename it to '{0}'", recommended_script_name);
diff --git a/lldb/unittests/Platform/PlatformTest.cpp b/lldb/unittests/Platform/PlatformTest.cpp
index 3f46353e1bcb8..1769282459eee 100644
--- a/lldb/unittests/Platform/PlatformTest.cpp
+++ b/lldb/unittests/Platform/PlatformTest.cpp
@@ -18,6 +18,7 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Platform.h"
+#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
@@ -225,11 +226,10 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", module_dir);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- ASSERT_EQ(file_specs.GetSize(), 0u);
+ ASSERT_EQ(file_specs.size(), 0u);
}
TEST_F(PlatformLocateSafePathTest,
@@ -252,11 +252,10 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule1.py", module_dir);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- ASSERT_EQ(file_specs.GetSize(), 0u);
+ ASSERT_EQ(file_specs.size(), 0u);
}
TEST_F(PlatformLocateSafePathTest,
@@ -281,12 +280,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("not_a_script.txt", module_dir);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "TestModule.py");
+ EXPECT_EQ(file_specs.size(), 1u);
+
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_EQ(fspec.GetFilename(), "TestModule.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
}
TEST_F(PlatformLocateSafePathTest,
@@ -313,11 +314,10 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", nested_dir);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.GetSize(), 0u);
+ EXPECT_EQ(file_specs.size(), 0u);
}
TEST_F(PlatformLocateSafePathTest,
@@ -373,15 +373,14 @@ TEST_F(PlatformLocateSafePathTest,
FileSpec(path2));
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
// path1 was the last appended path with a matching directory.
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_TRUE(llvm::StringRef(file_specs.GetFileSpecAtIndex(0).GetPath())
- .contains("AnotherSafePath"));
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "TestModule.py");
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_TRUE(llvm::StringRef(fspec.GetPath()).contains("AnotherSafePath"));
+ EXPECT_EQ(fspec.GetFilename(), "TestModule.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
// Now add another safe path with a valid module directory but no
// TestModule.py inside. LLDB shouldn't fall back to other matching safe
@@ -393,7 +392,7 @@ TEST_F(PlatformLocateSafePathTest,
file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.GetSize(), 0u);
+ EXPECT_EQ(file_specs.size(), 0u);
// Now place the correctly named script in path3.
CreateFile("TestModule.py", path3_module_dir);
@@ -401,10 +400,12 @@ TEST_F(PlatformLocateSafePathTest,
file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_TRUE(llvm::StringRef(file_specs.GetFileSpecAtIndex(0).GetPath())
- .contains("EmptySafePath"));
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "TestModule.py");
+ EXPECT_EQ(file_specs.size(), 1u);
+
+ auto [fspec1, load_style1] = *file_specs.begin();
+ EXPECT_TRUE(llvm::StringRef(fspec1.GetPath()).contains("EmptySafePath"));
+ EXPECT_EQ(fspec1.GetFilename(), "TestModule.py");
+ EXPECT_EQ(load_style1, m_target_sp->GetLoadScriptFromSymbolFile());
}
TEST_F(PlatformLocateSafePathTest,
@@ -428,11 +429,10 @@ TEST_F(PlatformLocateSafePathTest,
ASSERT_TRUE(orig_fspec);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.GetSize(), 0u);
+ EXPECT_EQ(file_specs.size(), 0u);
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because"
@@ -465,13 +465,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule_1_1_1.py", module_dir);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(),
- "TestModule_1_1_1.py");
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_EQ(fspec.GetFilename(), "TestModule_1_1_1.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because"
@@ -500,13 +501,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule_1_1_1.py", module_dir);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(),
- "TestModule_1_1_1.py");
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_EQ(fspec.GetFilename(), "TestModule_1_1_1.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
EXPECT_TRUE(ss.GetString().empty());
}
@@ -530,11 +532,10 @@ TEST_F(PlatformLocateSafePathTest,
ASSERT_TRUE(orig_fspec);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.GetSize(), 0u);
+ EXPECT_EQ(file_specs.size(), 0u);
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because 'import.py' "
@@ -566,12 +567,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("_import.py", module_dir);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "_import.py");
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_EQ(fspec.GetFilename(), "_import.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
std::string expected =
llvm::formatv("debug script '{0}' cannot be loaded because 'import.py' "
@@ -600,12 +603,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("_import.py", module_dir);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "_import.py");
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_EQ(fspec.GetFilename(), "_import.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
EXPECT_TRUE(ss.GetString().empty());
}
@@ -629,11 +634,10 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", inner_dir);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.GetSize(), 0u);
+ EXPECT_EQ(file_specs.size(), 0u);
EXPECT_TRUE(ss.GetString().empty());
}
@@ -662,11 +666,10 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", module_dir);
StreamString ss;
- FileSpecList file_specs =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.GetSize(), 1u);
+ EXPECT_EQ(file_specs.size(), 1u);
EXPECT_TRUE(ss.GetString().empty());
}
#endif // NDEBUG
>From 94285e5bae6341e33e4e59243257f6bcc3060abf Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Thu, 26 Mar 2026 09:13:03 +0000
Subject: [PATCH 2/7] [lldb] Add setting to specify (by name) which module's
scripting resources can be auto-loaded
This is part of [this RFC](https://discourse.llvm.org/t/rfc-lldb-moving-libc-data-formatters-out-of-lldb/89591) which is about turning the libc++ data-formatters into auto-loadable Python scripts.
Eventually we want the Python data-formatters for `libc++` to be automatically loaded without requiring user opt-in (since that's how the builtin formatters have always worked and, in my opinion, we can't transition to an opt-in model if users have always had the data-formatters available). To do so we need a way to distinguish which modules we can *always* auto-load from safe-paths, and which require `target.load-script-from-symbol-file` to be set to `true`.
This patch adds a setting (`target.auto-load-modules`) that is a dictionary from module-name to a boolean indicating whether the scripts for that module can be automatically loaded.
Making this a setting also means a user can disable any auto-loading by clearing it. By default the setting is currently empty. Eventually we'll want it to contain `libc++.1=true` (and possibly other names which the `libc++` dylib can commonly have).
**AI Usage**:
* Used Claude to generate the unit-test cases and shell tests. Reviewed and cleaned them up myself.
---
lldb/include/lldb/Target/Platform.h | 16 +-
lldb/include/lldb/Target/Target.h | 4 +
lldb/source/Core/Module.cpp | 20 +-
lldb/source/Target/Platform.cpp | 52 +++-
lldb/source/Target/Target.cpp | 14 +
lldb/source/Target/TargetProperties.td | 5 +
.../UNIX/auto-load-modules-false.test | 25 ++
.../UNIX/auto-load-modules-multiple.test | 38 +++
.../UNIX/auto-load-modules-not-in-dict.test | 29 ++
.../AutoLoad/UNIX/auto-load-modules-true.test | 26 ++
lldb/unittests/Platform/PlatformTest.cpp | 282 ++++++++++++++----
11 files changed, 435 insertions(+), 76 deletions(-)
create mode 100644 lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-false.test
create mode 100644 lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-multiple.test
create mode 100644 lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-not-in-dict.test
create mode 100644 lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-true.test
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 6bdaf10ef0713..1a4a00462ba7b 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -273,9 +273,13 @@ class Platform : public PluginInterface {
/// Locate the scripting resource given a module specification.
///
- /// Returns a map from a located script's \c FileSpec to the
- /// \c LoadScriptFromSymFile with which LLDB should load it.
- llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+ /// Locating the file should happen only on the local computer or using the
+ /// current computers global settings.
+ ///
+ /// Returns a pair of \c FileSpecList. The first element contains
+ /// scripts that are eligible to be auto-loaded. The second element
+ /// contains the non-auto loadable scripts.
+ std::pair<FileSpecList, FileSpecList>
LocateExecutableScriptingResources(Target *target, Module &module,
Stream &feedback_stream);
@@ -289,9 +293,13 @@ class Platform : public PluginInterface {
/// which gathers FileSpecs for executable scripts from
/// pre-configured "safe" auto-load paths.
///
+ /// Returns a pair of \c FileSpecList. The first element contains
+ /// scripts that are eligible to be auto-loaded. The second element
+ /// contains the non-auto loadable scripts.
+ ///
/// E.g., for Python it will look for a script at:
/// \c <safe-path>/<module-name>/<module-name>.py
- static llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+ static std::pair<FileSpecList, FileSpecList>
LocateExecutableScriptingResourcesFromSafePaths(Stream &feedback_stream,
FileSpec module_spec,
const Target &target);
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 7907ed2f1a5f6..a9f602bb7873f 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -278,6 +278,10 @@ class TargetProperties : public Properties {
bool GetDebugUtilityExpression() const;
+ OptionValueDictionary *GetAutoLoadModules() const;
+
+ void SetAutoLoadModule(llvm::StringRef module_name, bool should_load);
+
private:
std::optional<bool>
GetExperimentalPropertyValue(size_t prop_idx,
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 455d50c965d72..c196e36fa999d 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1439,6 +1439,9 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error) {
return false;
}
+ LoadScriptFromSymFile should_load =
+ target->TargetProperties::GetLoadScriptFromSymbolFile();
+
Debugger &debugger = target->GetDebugger();
const ScriptLanguage script_language = debugger.GetScriptLanguage();
if (script_language == eScriptLanguageNone)
@@ -1458,17 +1461,28 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error) {
}
StreamString feedback_stream;
- llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> file_specs =
+ const auto [auto_load_files, non_auto_load_files] =
platform_sp->LocateExecutableScriptingResources(target, *this,
feedback_stream);
if (!feedback_stream.Empty())
debugger.ReportWarning(feedback_stream.GetString().str(), debugger.GetID());
- for (const auto &[scripting_fspec, load_style] : file_specs) {
- if (load_style == eLoadScriptFromSymFileFalse)
+ for (uint32_t i = 0; i < auto_load_files.GetSize(); ++i) {
+ FileSpec scripting_fspec(auto_load_files.GetFileSpecAtIndex(i));
+ if (!FileSystem::Instance().Exists(scripting_fspec))
continue;
+ if (!LoadScriptingModule(scripting_fspec, *script_interpreter, *target,
+ error))
+ return false;
+ }
+
+ if (should_load == eLoadScriptFromSymFileFalse)
+ return !auto_load_files.IsEmpty();
+
+ for (uint32_t i = 0; i < non_auto_load_files.GetSize(); ++i) {
+ FileSpec scripting_fspec(non_auto_load_files.GetFileSpecAtIndex(i));
if (!FileSystem::Instance().Exists(scripting_fspec))
continue;
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index a676c50ef77ed..bde09d50c8aff 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -24,6 +24,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/OptionValueDictionary.h"
#include "lldb/Interpreter/OptionValueFileSpec.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Property.h"
@@ -157,7 +158,36 @@ Status Platform::GetFileWithUUID(const FileSpec &platform_file,
return Status();
}
-llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+// FIXME: move this into lldb-private-enumerations.h?
+enum class OptionalBool {
+ eYes,
+ eNo,
+ eDontKnow,
+};
+
+/// Returns \c OptionalBool::eYes if scripting resources associated with the
+/// specified module \c FileSpec can be automatically loaded. If a module is
+/// explicitly disallowed from being auto-loaded, returns \c OptionalBool::eNo.
+/// In all other cases, returns \c OptionalBool::eDontKnow.
+static OptionalBool CanAutoLoadModule(const FileSpec &module_fspec,
+ const Target &target) {
+ OptionValueDictionary *names = target.GetAutoLoadModules();
+ if (!names)
+ return OptionalBool::eDontKnow;
+
+ OptionValueSP value_sp =
+ names->GetValueForKey(module_fspec.GetFileNameStrippingExtension());
+ if (!value_sp)
+ return OptionalBool::eDontKnow;
+
+ auto maybe_can_load = value_sp->GetValueAs<bool>();
+ if (!maybe_can_load)
+ return OptionalBool::eDontKnow;
+
+ return *maybe_can_load ? OptionalBool::eYes : OptionalBool::eNo;
+}
+
+std::pair<FileSpecList, FileSpecList>
Platform::LocateExecutableScriptingResourcesFromSafePaths(
Stream &feedback_stream, FileSpec module_spec, const Target &target) {
assert(module_spec);
@@ -175,6 +205,8 @@ Platform::LocateExecutableScriptingResourcesFromSafePaths(
->GetSanitizedScriptingModuleName(
module_spec.GetFileNameStrippingExtension().GetStringRef());
+ FileSpecList non_auto_load_files;
+ FileSpecList auto_load_files;
FileSpecList paths = Debugger::GetSafeAutoLoadPaths();
// Iterate in reverse so we consider the latest appended path first.
@@ -198,16 +230,20 @@ Platform::LocateExecutableScriptingResourcesFromSafePaths(
WarnIfInvalidUnsanitizedScriptExists(feedback_stream, sanitized_name,
orig_script_fspec, script_fspec);
- if (FileSystem::Instance().Exists(script_fspec))
- file_specs.try_emplace(std::move(script_fspec),
- target.GetLoadScriptFromSymbolFile());
+ if (FileSystem::Instance().Exists(script_fspec)) {
+ OptionalBool can_auto_load = CanAutoLoadModule(module_spec, target);
+ if (can_auto_load == OptionalBool::eYes)
+ auto_load_files.Append(script_fspec);
+ else if (can_auto_load == OptionalBool::eDontKnow)
+ non_auto_load_files.Append(script_fspec);
+ }
// If we successfully found a directory in a safe auto-load path
// stop looking at any other paths.
break;
}
- return file_specs;
+ return {auto_load_files, non_auto_load_files};
}
llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
@@ -217,7 +253,7 @@ Platform::LocateExecutableScriptingResourcesForPlatform(
return empty;
}
-llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
+std::pair<FileSpecList, FileSpecList>
Platform::LocateExecutableScriptingResources(Target *target, Module &module,
Stream &feedback_stream) {
llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> empty;
@@ -227,8 +263,8 @@ Platform::LocateExecutableScriptingResources(Target *target, Module &module,
// Give derived platforms a chance to locate scripting resources.
if (auto fspecs = LocateExecutableScriptingResourcesForPlatform(
target, module, feedback_stream);
- !fspecs.empty())
- return fspecs;
+ !fspecs.IsEmpty())
+ return {{}, fspecs};
const FileSpec &module_spec = module.GetFileSpec();
if (!module_spec)
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 126a2b57ed4b4..cd0fe4e3eea58 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -5266,6 +5266,20 @@ void TargetProperties::SetDebugUtilityExpression(bool debug) {
SetPropertyAtIndex(idx, debug);
}
+OptionValueDictionary *TargetProperties::GetAutoLoadModules() const {
+ return m_collection_sp->GetPropertyAtIndexAsOptionValueDictionary(
+ ePropertyAutoLoadModules);
+}
+
+void TargetProperties::SetAutoLoadModule(llvm::StringRef module_name,
+ bool should_load) {
+ OptionValueDictionary *dict = GetAutoLoadModules();
+ if (!dict)
+ return;
+ dict->SetValueForKey(module_name,
+ std::make_shared<OptionValueBoolean>(should_load));
+}
+
// Target::TargetEventData
Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp)
diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td
index 2361314d506ac..d8ef0df70e7f8 100644
--- a/lldb/source/Target/TargetProperties.td
+++ b/lldb/source/Target/TargetProperties.td
@@ -220,6 +220,11 @@ let Definition = "target", Path = "target" in {
def ParallelModuleLoad: Property<"parallel-module-load", "Boolean">,
DefaultTrue,
Desc<"Enable loading of modules in parallel for the dynamic loader.">;
+ def AutoLoadModules
+ : Property<"auto-load-modules", "Dictionary">,
+ ElementType<"Boolean">,
+ Desc<"A list of module names and whether LLDB will auto-load scripting "
+ "resources for it from safe paths.">;
}
let Definition = "process_experimental", Path = "target.process.experimental" in {
diff --git a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-false.test b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-false.test
new file mode 100644
index 0000000000000..2902df479979c
--- /dev/null
+++ b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-false.test
@@ -0,0 +1,25 @@
+# REQUIRES: python, asserts, !system-windows
+
+# Test that when a module is listed in target.auto-load-modules with 'false',
+# its scripting resources are NOT loaded even when target.load-script-from-symbol-file
+# is true.
+
+# RUN: split-file %s %t
+# RUN: %clang_host %t/main.c -o %t/TestModule.out
+# RUN: mkdir -p %t/safe-path/TestModule
+
+# RUN: cp %t/script.py %t/safe-path/TestModule/TestModule.py
+# RUN: %lldb -b \
+# RUN: -o 'settings set target.load-script-from-symbol-file true' \
+# RUN: -o 'settings append testing.safe-auto-load-paths %t/safe-path' \
+# RUN: -o 'settings set target.auto-load-modules TestModule=false' \
+# RUN: -o 'target create %t/TestModule.out' 2>&1 \
+# RUN: | FileCheck %s --implicit-check-not=AUTOLOAD_SUCCESS --implicit-check-not=warning
+
+#--- main.c
+int main() { return 0; }
+
+#--- script.py
+import sys
+def __lldb_init_module(debugger, internal_dict):
+ print("AUTOLOAD_SUCCESS", file=sys.stderr)
diff --git a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-multiple.test b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-multiple.test
new file mode 100644
index 0000000000000..a9de987017641
--- /dev/null
+++ b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-multiple.test
@@ -0,0 +1,38 @@
+# REQUIRES: python, asserts, !system-windows
+
+# Test that multiple modules listed in target.auto-load-modules are all
+# auto-loaded.
+
+# RUN: split-file %s %t
+# RUN: %clang_host -shared %t/lib.c -o %t/libFoo.dylib
+# RUN: %clang_host %t/main.c -o %t/TestModule.out %t/libFoo.dylib
+# RUN: mkdir -p %t/safe-path/TestModule
+# RUN: mkdir -p %t/safe-path/libFoo
+
+# RUN: cp %t/main_script.py %t/safe-path/TestModule/TestModule.py
+# RUN: cp %t/lib_script.py %t/safe-path/libFoo/libFoo.py
+# RUN: %lldb -b \
+# RUN: -o 'settings set target.load-script-from-symbol-file false' \
+# RUN: -o 'settings append testing.safe-auto-load-paths %t/safe-path' \
+# RUN: -o 'settings set target.auto-load-modules TestModule=true libFoo=true' \
+# RUN: -o 'target create %t/TestModule.out' 2>&1 | FileCheck %s
+
+# CHECK-DAG: MAIN_AUTOLOAD_SUCCESS
+# CHECK-DAG: LIB_AUTOLOAD_SUCCESS
+
+#--- main.c
+extern int foo(void);
+int main() { return foo(); }
+
+#--- lib.c
+int foo(void) { return 0; }
+
+#--- main_script.py
+import sys
+def __lldb_init_module(debugger, internal_dict):
+ print("MAIN_AUTOLOAD_SUCCESS", file=sys.stderr)
+
+#--- lib_script.py
+import sys
+def __lldb_init_module(debugger, internal_dict):
+ print("LIB_AUTOLOAD_SUCCESS", file=sys.stderr)
diff --git a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-not-in-dict.test b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-not-in-dict.test
new file mode 100644
index 0000000000000..cf9a80121c17a
--- /dev/null
+++ b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-not-in-dict.test
@@ -0,0 +1,29 @@
+# REQUIRES: python, asserts, !system-windows
+
+# Test that when a module is NOT in target.auto-load-modules, the existing
+# target.load-script-from-symbol-file setting controls whether scripts load.
+# With load-script-from-symbol-file=true and no dictionary entry, scripts
+# should still load normally.
+
+# RUN: split-file %s %t
+# RUN: %clang_host %t/main.c -o %t/TestModule.out
+# RUN: mkdir -p %t/safe-path/TestModule
+
+# RUN: cp %t/script.py %t/safe-path/TestModule/TestModule.py
+
+## A different module is in the dictionary; TestModule is not.
+# RUN: %lldb -b \
+# RUN: -o 'settings set target.load-script-from-symbol-file warn' \
+# RUN: -o 'settings append testing.safe-auto-load-paths %t/safe-path' \
+# RUN: -o 'settings set target.auto-load-modules SomeOtherModule=true' \
+# RUN: -o 'target create %t/TestModule.out' 2>&1 | FileCheck %s --implicit-check-not=AUTOLOAD_SUCCESS
+
+# CHECK: warning: 'TestModule' contains a debug script. To run this script in this debug session
+
+#--- main.c
+int main() { return 0; }
+
+#--- script.py
+import sys
+def __lldb_init_module(debugger, internal_dict):
+ print("AUTOLOAD_SUCCESS", file=sys.stderr)
diff --git a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-true.test b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-true.test
new file mode 100644
index 0000000000000..87b09248b22f6
--- /dev/null
+++ b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-true.test
@@ -0,0 +1,26 @@
+# REQUIRES: python, asserts, !system-windows
+
+# Test that when a module is listed in target.auto-load-modules with 'true',
+# its scripting resources are loaded even when target.load-script-from-symbol-file
+# is false.
+
+# RUN: split-file %s %t
+# RUN: %clang_host %t/main.c -o %t/TestModule.out
+# RUN: mkdir -p %t/safe-path/TestModule
+
+# RUN: cp %t/script.py %t/safe-path/TestModule/TestModule.py
+# RUN: %lldb -b \
+# RUN: -o 'settings set target.load-script-from-symbol-file false' \
+# RUN: -o 'settings append testing.safe-auto-load-paths %t/safe-path' \
+# RUN: -o 'settings set target.auto-load-modules TestModule=true' \
+# RUN: -o 'target create %t/TestModule.out' 2>&1 | FileCheck %s
+
+# CHECK: AUTOLOAD_SUCCESS
+
+#--- main.c
+int main() { return 0; }
+
+#--- script.py
+import sys
+def __lldb_init_module(debugger, internal_dict):
+ print("AUTOLOAD_SUCCESS", file=sys.stderr)
diff --git a/lldb/unittests/Platform/PlatformTest.cpp b/lldb/unittests/Platform/PlatformTest.cpp
index 1769282459eee..18608f6fba939 100644
--- a/lldb/unittests/Platform/PlatformTest.cpp
+++ b/lldb/unittests/Platform/PlatformTest.cpp
@@ -226,10 +226,12 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", module_dir);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- ASSERT_EQ(file_specs.size(), 0u);
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ ASSERT_EQ(file_specs.GetSize(), 0u);
}
TEST_F(PlatformLocateSafePathTest,
@@ -252,10 +254,12 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule1.py", module_dir);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- ASSERT_EQ(file_specs.size(), 0u);
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ ASSERT_EQ(file_specs.GetSize(), 0u);
}
TEST_F(PlatformLocateSafePathTest,
@@ -280,14 +284,13 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("not_a_script.txt", module_dir);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.size(), 1u);
-
- auto [fspec, load_style] = *file_specs.begin();
- EXPECT_EQ(fspec.GetFilename(), "TestModule.py");
- EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ EXPECT_EQ(file_specs.GetSize(), 1u);
+ EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "TestModule.py");
}
TEST_F(PlatformLocateSafePathTest,
@@ -314,10 +317,12 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", nested_dir);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.size(), 0u);
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ EXPECT_EQ(file_specs.GetSize(), 0u);
}
TEST_F(PlatformLocateSafePathTest,
@@ -373,8 +378,11 @@ TEST_F(PlatformLocateSafePathTest,
FileSpec(path2));
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
// path1 was the last appended path with a matching directory.
auto [fspec, load_style] = *file_specs.begin();
@@ -390,7 +398,8 @@ TEST_F(PlatformLocateSafePathTest,
FileSpec(path3));
file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ ss, module_fspec, *m_target_sp)
+ .second;
EXPECT_EQ(file_specs.size(), 0u);
@@ -398,7 +407,8 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", path3_module_dir);
file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ ss, module_fspec, *m_target_sp)
+ .second;
EXPECT_EQ(file_specs.size(), 1u);
@@ -429,10 +439,12 @@ TEST_F(PlatformLocateSafePathTest,
ASSERT_TRUE(orig_fspec);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.size(), 0u);
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ EXPECT_EQ(file_specs.GetSize(), 0u);
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because"
@@ -465,14 +477,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule_1_1_1.py", module_dir);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
-
- EXPECT_EQ(file_specs.size(), 1u);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- auto [fspec, load_style] = *file_specs.begin();
- EXPECT_EQ(fspec.GetFilename(), "TestModule_1_1_1.py");
- EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ EXPECT_EQ(file_specs.GetSize(), 1u);
+ EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(),
+ "TestModule_1_1_1.py");
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because"
@@ -501,14 +513,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule_1_1_1.py", module_dir);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
-
- EXPECT_EQ(file_specs.size(), 1u);
-
- auto [fspec, load_style] = *file_specs.begin();
- EXPECT_EQ(fspec.GetFilename(), "TestModule_1_1_1.py");
- EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ EXPECT_EQ(file_specs.GetSize(), 1u);
+ EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(),
+ "TestModule_1_1_1.py");
EXPECT_TRUE(ss.GetString().empty());
}
@@ -532,10 +544,12 @@ TEST_F(PlatformLocateSafePathTest,
ASSERT_TRUE(orig_fspec);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.size(), 0u);
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ EXPECT_EQ(file_specs.GetSize(), 0u);
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because 'import.py' "
@@ -567,14 +581,13 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("_import.py", module_dir);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.size(), 1u);
-
- auto [fspec, load_style] = *file_specs.begin();
- EXPECT_EQ(fspec.GetFilename(), "_import.py");
- EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ EXPECT_EQ(file_specs.GetSize(), 1u);
+ EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "_import.py");
std::string expected =
llvm::formatv("debug script '{0}' cannot be loaded because 'import.py' "
@@ -603,14 +616,13 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("_import.py", module_dir);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
-
- EXPECT_EQ(file_specs.size(), 1u);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- auto [fspec, load_style] = *file_specs.begin();
- EXPECT_EQ(fspec.GetFilename(), "_import.py");
- EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ EXPECT_EQ(file_specs.GetSize(), 1u);
+ EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "_import.py");
EXPECT_TRUE(ss.GetString().empty());
}
@@ -634,10 +646,12 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", inner_dir);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.size(), 0u);
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ EXPECT_EQ(file_specs.GetSize(), 0u);
EXPECT_TRUE(ss.GetString().empty());
}
@@ -666,10 +680,156 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", module_dir);
StreamString ss;
- auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto [auto_load_spces, file_specs] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(file_specs.size(), 1u);
+ EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ EXPECT_EQ(file_specs.GetSize(), 1u);
EXPECT_TRUE(ss.GetString().empty());
}
+
+TEST_F(PlatformLocateSafePathTest,
+ LocateScriptingResourcesFromSafePaths_AutoLoadModule_True) {
+ // When a module is in target.auto-load-modules with value 'true',
+ // its script should be returned in the auto-load list.
+
+ TestingProperties::GetGlobalTestingProperties().AppendSafeAutoLoadPaths(
+ FileSpec(m_tmp_root_dir));
+
+ FileSpec module_fspec(CreateFile("TestModule.o", m_tmp_root_dir));
+ ASSERT_TRUE(module_fspec);
+
+ llvm::SmallString<128> module_dir(m_tmp_root_dir);
+ llvm::sys::path::append(module_dir, "TestModule");
+ ASSERT_FALSE(llvm::sys::fs::create_directory(module_dir));
+
+ CreateFile("TestModule.py", module_dir);
+
+ m_target_sp->SetAutoLoadModule("TestModule", true);
+
+ StreamString ss;
+ auto [auto_load_files, non_auto_load_files] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(auto_load_files.GetSize(), 1u);
+ EXPECT_EQ(auto_load_files.GetFileSpecAtIndex(0).GetFilename(),
+ "TestModule.py");
+ EXPECT_EQ(non_auto_load_files.GetSize(), 0u);
+}
+
+TEST_F(PlatformLocateSafePathTest,
+ LocateScriptingResourcesFromSafePaths_AutoLoadModule_False) {
+ // When a module is in target.auto-load-modules with value 'false',
+ // its script should not appear in either list.
+
+ TestingProperties::GetGlobalTestingProperties().AppendSafeAutoLoadPaths(
+ FileSpec(m_tmp_root_dir));
+
+ FileSpec module_fspec(CreateFile("TestModule.o", m_tmp_root_dir));
+ ASSERT_TRUE(module_fspec);
+
+ llvm::SmallString<128> module_dir(m_tmp_root_dir);
+ llvm::sys::path::append(module_dir, "TestModule");
+ ASSERT_FALSE(llvm::sys::fs::create_directory(module_dir));
+
+ CreateFile("TestModule.py", module_dir);
+
+ m_target_sp->SetAutoLoadModule("TestModule", false);
+
+ StreamString ss;
+ auto [auto_load_files, non_auto_load_files] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(auto_load_files.GetSize(), 0u);
+ EXPECT_EQ(non_auto_load_files.GetSize(), 0u);
+}
+
+TEST_F(PlatformLocateSafePathTest,
+ LocateScriptingResourcesFromSafePaths_AutoLoadModule_NotInDict) {
+ // When a module is NOT in the dictionary, its script should end up
+ // in the non-auto-load list (the existing behavior).
+
+ TestingProperties::GetGlobalTestingProperties().AppendSafeAutoLoadPaths(
+ FileSpec(m_tmp_root_dir));
+
+ FileSpec module_fspec(CreateFile("TestModule.o", m_tmp_root_dir));
+ ASSERT_TRUE(module_fspec);
+
+ llvm::SmallString<128> module_dir(m_tmp_root_dir);
+ llvm::sys::path::append(module_dir, "TestModule");
+ ASSERT_FALSE(llvm::sys::fs::create_directory(module_dir));
+
+ CreateFile("TestModule.py", module_dir);
+
+ // Set a different module in the dictionary; TestModule is not present.
+ m_target_sp->SetAutoLoadModule("SomeOtherModule", true);
+
+ StreamString ss;
+ auto [auto_load_files, non_auto_load_files] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(auto_load_files.GetSize(), 0u);
+ EXPECT_EQ(non_auto_load_files.GetSize(), 1u);
+ EXPECT_EQ(non_auto_load_files.GetFileSpecAtIndex(0).GetFilename(),
+ "TestModule.py");
+}
+
+TEST_F(PlatformLocateSafePathTest,
+ LocateScriptingResourcesFromSafePaths_AutoLoadModule_Multiple) {
+ // When multiple modules are in target.auto-load-modules with value 'true',
+ // each module's script should be returned in its respective auto-load list.
+
+ TestingProperties::GetGlobalTestingProperties().AppendSafeAutoLoadPaths(
+ FileSpec(m_tmp_root_dir));
+
+ // Set up ModuleA.
+ FileSpec module_a_fspec(CreateFile("ModuleA.o", m_tmp_root_dir));
+ ASSERT_TRUE(module_a_fspec);
+
+ llvm::SmallString<128> module_a_dir(m_tmp_root_dir);
+ llvm::sys::path::append(module_a_dir, "ModuleA");
+ ASSERT_FALSE(llvm::sys::fs::create_directory(module_a_dir));
+ CreateFile("ModuleA.py", module_a_dir);
+
+ // Set up ModuleB.
+ FileSpec module_b_fspec(CreateFile("ModuleB.o", m_tmp_root_dir));
+ ASSERT_TRUE(module_b_fspec);
+
+ llvm::SmallString<128> module_b_dir(m_tmp_root_dir);
+ llvm::sys::path::append(module_b_dir, "ModuleB");
+ ASSERT_FALSE(llvm::sys::fs::create_directory(module_b_dir));
+ CreateFile("ModuleB.py", module_b_dir);
+
+ m_target_sp->SetAutoLoadModule("ModuleA", true);
+ m_target_sp->SetAutoLoadModule("ModuleB", true);
+
+ {
+ StreamString ss;
+ auto [auto_load_files, non_auto_load_files] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_a_fspec, *m_target_sp);
+
+ EXPECT_EQ(auto_load_files.GetSize(), 1u);
+ EXPECT_EQ(auto_load_files.GetFileSpecAtIndex(0).GetFilename(),
+ "ModuleA.py");
+ EXPECT_EQ(non_auto_load_files.GetSize(), 0u);
+ }
+
+ {
+ StreamString ss;
+ auto [auto_load_files, non_auto_load_files] =
+ Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_b_fspec, *m_target_sp);
+
+ EXPECT_EQ(auto_load_files.GetSize(), 1u);
+ EXPECT_EQ(auto_load_files.GetFileSpecAtIndex(0).GetFilename(),
+ "ModuleB.py");
+ EXPECT_EQ(non_auto_load_files.GetSize(), 0u);
+ }
+}
+
#endif // NDEBUG
>From bbd4864da12240a9d071e5567b10e4bd67c80144 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 27 Mar 2026 10:56:29 +0000
Subject: [PATCH 3/7] fixup! rename setting
---
lldb/include/lldb/Target/Target.h | 5 +++--
lldb/source/Target/Target.cpp | 10 +++++-----
lldb/source/Target/TargetProperties.td | 4 ++--
.../AutoLoad/UNIX/auto-load-modules-false.test | 4 ++--
.../AutoLoad/UNIX/auto-load-modules-multiple.test | 4 ++--
.../AutoLoad/UNIX/auto-load-modules-not-in-dict.test | 4 ++--
.../AutoLoad/UNIX/auto-load-modules-true.test | 4 ++--
lldb/unittests/Platform/PlatformTest.cpp | 11 ++++++-----
8 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index a9f602bb7873f..8edac8d4017af 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -278,9 +278,10 @@ class TargetProperties : public Properties {
bool GetDebugUtilityExpression() const;
- OptionValueDictionary *GetAutoLoadModules() const;
+ OptionValueDictionary *GetAutoLoadScriptsForModules() const;
- void SetAutoLoadModule(llvm::StringRef module_name, bool should_load);
+ void SetAutoLoadScriptsForModules(llvm::StringRef module_name,
+ bool should_load);
private:
std::optional<bool>
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index cd0fe4e3eea58..b6b647c62628d 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -5266,14 +5266,14 @@ void TargetProperties::SetDebugUtilityExpression(bool debug) {
SetPropertyAtIndex(idx, debug);
}
-OptionValueDictionary *TargetProperties::GetAutoLoadModules() const {
+OptionValueDictionary *TargetProperties::GetAutoLoadScriptsForModules() const {
return m_collection_sp->GetPropertyAtIndexAsOptionValueDictionary(
- ePropertyAutoLoadModules);
+ ePropertyAutoLoadScriptsForModules);
}
-void TargetProperties::SetAutoLoadModule(llvm::StringRef module_name,
- bool should_load) {
- OptionValueDictionary *dict = GetAutoLoadModules();
+void TargetProperties::SetAutoLoadScriptsForModules(llvm::StringRef module_name,
+ bool should_load) {
+ OptionValueDictionary *dict = GetAutoLoadScriptsForModules();
if (!dict)
return;
dict->SetValueForKey(module_name,
diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td
index d8ef0df70e7f8..a54c6090fa82a 100644
--- a/lldb/source/Target/TargetProperties.td
+++ b/lldb/source/Target/TargetProperties.td
@@ -220,8 +220,8 @@ let Definition = "target", Path = "target" in {
def ParallelModuleLoad: Property<"parallel-module-load", "Boolean">,
DefaultTrue,
Desc<"Enable loading of modules in parallel for the dynamic loader.">;
- def AutoLoadModules
- : Property<"auto-load-modules", "Dictionary">,
+ def AutoLoadScriptsForModules
+ : Property<"auto-load-scripts-for-modules", "Dictionary">,
ElementType<"Boolean">,
Desc<"A list of module names and whether LLDB will auto-load scripting "
"resources for it from safe paths.">;
diff --git a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-false.test b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-false.test
index 2902df479979c..7154d52e8f6a2 100644
--- a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-false.test
+++ b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-false.test
@@ -1,6 +1,6 @@
# REQUIRES: python, asserts, !system-windows
-# Test that when a module is listed in target.auto-load-modules with 'false',
+# Test that when a module is listed in target.auto-load-scripts-for-modules with 'false',
# its scripting resources are NOT loaded even when target.load-script-from-symbol-file
# is true.
@@ -12,7 +12,7 @@
# RUN: %lldb -b \
# RUN: -o 'settings set target.load-script-from-symbol-file true' \
# RUN: -o 'settings append testing.safe-auto-load-paths %t/safe-path' \
-# RUN: -o 'settings set target.auto-load-modules TestModule=false' \
+# RUN: -o 'settings set target.auto-load-scripts-for-modules TestModule=false' \
# RUN: -o 'target create %t/TestModule.out' 2>&1 \
# RUN: | FileCheck %s --implicit-check-not=AUTOLOAD_SUCCESS --implicit-check-not=warning
diff --git a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-multiple.test b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-multiple.test
index a9de987017641..d26c574ff2d5c 100644
--- a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-multiple.test
+++ b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-multiple.test
@@ -1,6 +1,6 @@
# REQUIRES: python, asserts, !system-windows
-# Test that multiple modules listed in target.auto-load-modules are all
+# Test that multiple modules listed in target.auto-load-scripts-for-modules are all
# auto-loaded.
# RUN: split-file %s %t
@@ -14,7 +14,7 @@
# RUN: %lldb -b \
# RUN: -o 'settings set target.load-script-from-symbol-file false' \
# RUN: -o 'settings append testing.safe-auto-load-paths %t/safe-path' \
-# RUN: -o 'settings set target.auto-load-modules TestModule=true libFoo=true' \
+# RUN: -o 'settings set target.auto-load-scripts-for-modules TestModule=true libFoo=true' \
# RUN: -o 'target create %t/TestModule.out' 2>&1 | FileCheck %s
# CHECK-DAG: MAIN_AUTOLOAD_SUCCESS
diff --git a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-not-in-dict.test b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-not-in-dict.test
index cf9a80121c17a..3213ae61558dd 100644
--- a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-not-in-dict.test
+++ b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-not-in-dict.test
@@ -1,6 +1,6 @@
# REQUIRES: python, asserts, !system-windows
-# Test that when a module is NOT in target.auto-load-modules, the existing
+# Test that when a module is NOT in target.auto-load-scripts-for-modules, the existing
# target.load-script-from-symbol-file setting controls whether scripts load.
# With load-script-from-symbol-file=true and no dictionary entry, scripts
# should still load normally.
@@ -15,7 +15,7 @@
# RUN: %lldb -b \
# RUN: -o 'settings set target.load-script-from-symbol-file warn' \
# RUN: -o 'settings append testing.safe-auto-load-paths %t/safe-path' \
-# RUN: -o 'settings set target.auto-load-modules SomeOtherModule=true' \
+# RUN: -o 'settings set target.auto-load-scripts-for-modules SomeOtherModule=true' \
# RUN: -o 'target create %t/TestModule.out' 2>&1 | FileCheck %s --implicit-check-not=AUTOLOAD_SUCCESS
# CHECK: warning: 'TestModule' contains a debug script. To run this script in this debug session
diff --git a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-true.test b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-true.test
index 87b09248b22f6..f1f2932cac55b 100644
--- a/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-true.test
+++ b/lldb/test/Shell/Platform/AutoLoad/UNIX/auto-load-modules-true.test
@@ -1,6 +1,6 @@
# REQUIRES: python, asserts, !system-windows
-# Test that when a module is listed in target.auto-load-modules with 'true',
+# Test that when a module is listed in target.auto-load-scripts-for-modules with 'true',
# its scripting resources are loaded even when target.load-script-from-symbol-file
# is false.
@@ -12,7 +12,7 @@
# RUN: %lldb -b \
# RUN: -o 'settings set target.load-script-from-symbol-file false' \
# RUN: -o 'settings append testing.safe-auto-load-paths %t/safe-path' \
-# RUN: -o 'settings set target.auto-load-modules TestModule=true' \
+# RUN: -o 'settings set target.auto-load-scripts-for-modules TestModule=true' \
# RUN: -o 'target create %t/TestModule.out' 2>&1 | FileCheck %s
# CHECK: AUTOLOAD_SUCCESS
diff --git a/lldb/unittests/Platform/PlatformTest.cpp b/lldb/unittests/Platform/PlatformTest.cpp
index 18608f6fba939..20b45ba1c84bc 100644
--- a/lldb/unittests/Platform/PlatformTest.cpp
+++ b/lldb/unittests/Platform/PlatformTest.cpp
@@ -691,7 +691,7 @@ TEST_F(PlatformLocateSafePathTest,
TEST_F(PlatformLocateSafePathTest,
LocateScriptingResourcesFromSafePaths_AutoLoadModule_True) {
- // When a module is in target.auto-load-modules with value 'true',
+ // When a module is in target.auto-load-scripts-for-modules with value 'true',
// its script should be returned in the auto-load list.
TestingProperties::GetGlobalTestingProperties().AppendSafeAutoLoadPaths(
@@ -721,8 +721,8 @@ TEST_F(PlatformLocateSafePathTest,
TEST_F(PlatformLocateSafePathTest,
LocateScriptingResourcesFromSafePaths_AutoLoadModule_False) {
- // When a module is in target.auto-load-modules with value 'false',
- // its script should not appear in either list.
+ // When a module is in target.auto-load-scripts-for-modules with value
+ // 'false', its script should not appear in either list.
TestingProperties::GetGlobalTestingProperties().AppendSafeAutoLoadPaths(
FileSpec(m_tmp_root_dir));
@@ -780,8 +780,9 @@ TEST_F(PlatformLocateSafePathTest,
TEST_F(PlatformLocateSafePathTest,
LocateScriptingResourcesFromSafePaths_AutoLoadModule_Multiple) {
- // When multiple modules are in target.auto-load-modules with value 'true',
- // each module's script should be returned in its respective auto-load list.
+ // When multiple modules are in target.auto-load-scripts-for-modules with
+ // value 'true', each module's script should be returned in its respective
+ // auto-load list.
TestingProperties::GetGlobalTestingProperties().AppendSafeAutoLoadPaths(
FileSpec(m_tmp_root_dir));
>From 97bc3be992fd8011164983c5087cd9d488247f9e Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 27 Mar 2026 10:59:05 +0000
Subject: [PATCH 4/7] fixup
---
lldb/source/Target/Platform.cpp | 2 +-
lldb/unittests/Platform/PlatformTest.cpp | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index bde09d50c8aff..007540f2ceabc 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -171,7 +171,7 @@ enum class OptionalBool {
/// In all other cases, returns \c OptionalBool::eDontKnow.
static OptionalBool CanAutoLoadModule(const FileSpec &module_fspec,
const Target &target) {
- OptionValueDictionary *names = target.GetAutoLoadModules();
+ OptionValueDictionary *names = target.GetAutoLoadScriptsForModules();
if (!names)
return OptionalBool::eDontKnow;
diff --git a/lldb/unittests/Platform/PlatformTest.cpp b/lldb/unittests/Platform/PlatformTest.cpp
index 20b45ba1c84bc..cea14b5a095c4 100644
--- a/lldb/unittests/Platform/PlatformTest.cpp
+++ b/lldb/unittests/Platform/PlatformTest.cpp
@@ -706,7 +706,7 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", module_dir);
- m_target_sp->SetAutoLoadModule("TestModule", true);
+ m_target_sp->SetAutoLoadScriptsForModules("TestModule", true);
StreamString ss;
auto [auto_load_files, non_auto_load_files] =
@@ -736,7 +736,7 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", module_dir);
- m_target_sp->SetAutoLoadModule("TestModule", false);
+ m_target_sp->SetAutoLoadScriptsForModules("TestModule", false);
StreamString ss;
auto [auto_load_files, non_auto_load_files] =
@@ -765,7 +765,7 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", module_dir);
// Set a different module in the dictionary; TestModule is not present.
- m_target_sp->SetAutoLoadModule("SomeOtherModule", true);
+ m_target_sp->SetAutoLoadScriptsForModules("SomeOtherModule", true);
StreamString ss;
auto [auto_load_files, non_auto_load_files] =
@@ -805,8 +805,8 @@ TEST_F(PlatformLocateSafePathTest,
ASSERT_FALSE(llvm::sys::fs::create_directory(module_b_dir));
CreateFile("ModuleB.py", module_b_dir);
- m_target_sp->SetAutoLoadModule("ModuleA", true);
- m_target_sp->SetAutoLoadModule("ModuleB", true);
+ m_target_sp->SetAutoLoadScriptsForModules("ModuleA", true);
+ m_target_sp->SetAutoLoadScriptsForModules("ModuleB", true);
{
StreamString ss;
>From 1036e6511304510ad3d85dd16512d2d59315c2b4 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 27 Mar 2026 11:00:47 +0000
Subject: [PATCH 5/7] fixup! fixup OptionalBool -> LazyBool
---
lldb/source/Target/Platform.cpp | 32 +++++++++++++-------------------
1 file changed, 13 insertions(+), 19 deletions(-)
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 007540f2ceabc..b081ddb719007 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -41,6 +41,7 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-private-enumerations.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
@@ -158,33 +159,26 @@ Status Platform::GetFileWithUUID(const FileSpec &platform_file,
return Status();
}
-// FIXME: move this into lldb-private-enumerations.h?
-enum class OptionalBool {
- eYes,
- eNo,
- eDontKnow,
-};
-
-/// Returns \c OptionalBool::eYes if scripting resources associated with the
+/// Returns \c eLazyBoolNo if scripting resources associated with the
/// specified module \c FileSpec can be automatically loaded. If a module is
-/// explicitly disallowed from being auto-loaded, returns \c OptionalBool::eNo.
-/// In all other cases, returns \c OptionalBool::eDontKnow.
-static OptionalBool CanAutoLoadModule(const FileSpec &module_fspec,
- const Target &target) {
+/// explicitly disallowed from being auto-loaded, returns \c eLazyBoolNo.
+/// In all other cases, returns \c eDontKnow.
+static LazyBool CanAutoLoadModule(const FileSpec &module_fspec,
+ const Target &target) {
OptionValueDictionary *names = target.GetAutoLoadScriptsForModules();
if (!names)
- return OptionalBool::eDontKnow;
+ return eLazyBoolCalculate;
OptionValueSP value_sp =
names->GetValueForKey(module_fspec.GetFileNameStrippingExtension());
if (!value_sp)
- return OptionalBool::eDontKnow;
+ return eLazyBoolCalculate;
auto maybe_can_load = value_sp->GetValueAs<bool>();
if (!maybe_can_load)
- return OptionalBool::eDontKnow;
+ return eLazyBoolCalculate;
- return *maybe_can_load ? OptionalBool::eYes : OptionalBool::eNo;
+ return *maybe_can_load ? eLazyBoolYes : eLazyBoolNo;
}
std::pair<FileSpecList, FileSpecList>
@@ -231,10 +225,10 @@ Platform::LocateExecutableScriptingResourcesFromSafePaths(
orig_script_fspec, script_fspec);
if (FileSystem::Instance().Exists(script_fspec)) {
- OptionalBool can_auto_load = CanAutoLoadModule(module_spec, target);
- if (can_auto_load == OptionalBool::eYes)
+ LazyBool can_auto_load = CanAutoLoadModule(module_spec, target);
+ if (can_auto_load == eLazyBoolYes)
auto_load_files.Append(script_fspec);
- else if (can_auto_load == OptionalBool::eDontKnow)
+ else if (can_auto_load == eLazyBoolCalculate)
non_auto_load_files.Append(script_fspec);
}
>From 1b16b0748521250a01a64d2894ce99cbddb5f124 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 27 Mar 2026 12:03:06 +0000
Subject: [PATCH 6/7] fixup! add log
---
lldb/source/Core/Module.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index c196e36fa999d..14e20fe358d57 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1473,6 +1473,9 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error) {
if (!FileSystem::Instance().Exists(scripting_fspec))
continue;
+ LLDB_LOG(GetLog(LLDBLog::Modules), "Auto-loading {0}",
+ scripting_fspec.GetPath());
+
if (!LoadScriptingModule(scripting_fspec, *script_interpreter, *target,
error))
return false;
>From 8a0efe94a6844538c467b34e5a5e940e1b954c40 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 31 Mar 2026 11:59:22 +0200
Subject: [PATCH 7/7] fixup! make setting dictionary element an enum
---
lldb/include/lldb/Target/Platform.h | 12 +-
lldb/source/Core/Module.cpp | 31 +--
.../Platform/MacOSX/PlatformDarwin.cpp | 5 +-
lldb/source/Target/Platform.cpp | 39 ++--
lldb/source/Target/TargetProperties.td | 3 +-
lldb/unittests/Platform/PlatformTest.cpp | 215 ++++++++----------
6 files changed, 142 insertions(+), 163 deletions(-)
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 1a4a00462ba7b..4a2d7e5b5ec32 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -279,7 +279,7 @@ class Platform : public PluginInterface {
/// Returns a pair of \c FileSpecList. The first element contains
/// scripts that are eligible to be auto-loaded. The second element
/// contains the non-auto loadable scripts.
- std::pair<FileSpecList, FileSpecList>
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
LocateExecutableScriptingResources(Target *target, Module &module,
Stream &feedback_stream);
@@ -299,7 +299,7 @@ class Platform : public PluginInterface {
///
/// E.g., for Python it will look for a script at:
/// \c <safe-path>/<module-name>/<module-name>.py
- static std::pair<FileSpecList, FileSpecList>
+ static llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
LocateExecutableScriptingResourcesFromSafePaths(Stream &feedback_stream,
FileSpec module_spec,
const Target &target);
@@ -1094,6 +1094,14 @@ class Platform : public PluginInterface {
const ScriptInterpreter::SanitizedScriptingModuleName &sanitized_name,
const FileSpec &original_fspec, const FileSpec &fspec);
+ /// Returns \c eLazyBoolNo if scripting resources associated with the
+ /// specified module \c FileSpec can be automatically loaded. If a module is
+ /// explicitly disallowed from being auto-loaded, returns \c eLazyBoolNo.
+ /// In all other cases, returns \c eDontKnow.
+ static LoadScriptFromSymFile
+ GetScriptLoadStyleForModule(const FileSpec &module_fspec,
+ const Target &target);
+
private:
typedef std::function<Status(const ModuleSpec &)> ModuleResolver;
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 14e20fe358d57..0130f8d2e9394 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1439,9 +1439,6 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error) {
return false;
}
- LoadScriptFromSymFile should_load =
- target->TargetProperties::GetLoadScriptFromSymbolFile();
-
Debugger &debugger = target->GetDebugger();
const ScriptLanguage script_language = debugger.GetScriptLanguage();
if (script_language == eScriptLanguageNone)
@@ -1461,31 +1458,17 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error) {
}
StreamString feedback_stream;
- const auto [auto_load_files, non_auto_load_files] =
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> file_specs =
platform_sp->LocateExecutableScriptingResources(target, *this,
feedback_stream);
if (!feedback_stream.Empty())
debugger.ReportWarning(feedback_stream.GetString().str(), debugger.GetID());
- for (uint32_t i = 0; i < auto_load_files.GetSize(); ++i) {
- FileSpec scripting_fspec(auto_load_files.GetFileSpecAtIndex(i));
- if (!FileSystem::Instance().Exists(scripting_fspec))
+ for (const auto &[scripting_fspec, load_style] : file_specs) {
+ if (load_style == eLoadScriptFromSymFileFalse)
continue;
- LLDB_LOG(GetLog(LLDBLog::Modules), "Auto-loading {0}",
- scripting_fspec.GetPath());
-
- if (!LoadScriptingModule(scripting_fspec, *script_interpreter, *target,
- error))
- return false;
- }
-
- if (should_load == eLoadScriptFromSymFileFalse)
- return !auto_load_files.IsEmpty();
-
- for (uint32_t i = 0; i < non_auto_load_files.GetSize(); ++i) {
- FileSpec scripting_fspec(non_auto_load_files.GetFileSpecAtIndex(i));
if (!FileSystem::Instance().Exists(scripting_fspec))
continue;
@@ -1506,15 +1489,19 @@ To run all discovered debug scripts in this session:
debugger.GetID());
// clang-format on
- return false;
+ continue;
}
LLDB_LOG(GetLog(LLDBLog::Modules), "Auto-loading {0}",
scripting_fspec.GetPath());
if (!LoadScriptingModule(scripting_fspec, *script_interpreter, *target,
- error))
+ error)) {
+ LLDB_LOG(GetLog(LLDBLog::Modules),
+ "Failed to load '{0}'. Remaining scripts won't be loaded.",
+ scripting_fspec.GetPath());
return false;
+ }
}
return true;
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index c6351b02791db..f756bf8cf9fad 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -235,8 +235,9 @@ PlatformDarwin::LocateExecutableScriptingResourcesFromDSYM(
orig_script_fspec, script_fspec);
if (FileSystem::Instance().Exists(script_fspec)) {
- file_specs.try_emplace(std::move(script_fspec),
- target.GetLoadScriptFromSymbolFile());
+ LoadScriptFromSymFile load_style =
+ Platform::GetScriptLoadStyleForModule(script_fspec, target);
+ file_specs.try_emplace(std::move(script_fspec), load_style);
break;
}
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index b081ddb719007..72d4594c77860 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -163,25 +163,26 @@ Status Platform::GetFileWithUUID(const FileSpec &platform_file,
/// specified module \c FileSpec can be automatically loaded. If a module is
/// explicitly disallowed from being auto-loaded, returns \c eLazyBoolNo.
/// In all other cases, returns \c eDontKnow.
-static LazyBool CanAutoLoadModule(const FileSpec &module_fspec,
- const Target &target) {
+LoadScriptFromSymFile
+Platform::GetScriptLoadStyleForModule(const FileSpec &module_fspec,
+ const Target &target) {
+ LoadScriptFromSymFile default_load_style =
+ target.GetLoadScriptFromSymbolFile();
+
OptionValueDictionary *names = target.GetAutoLoadScriptsForModules();
if (!names)
- return eLazyBoolCalculate;
+ return default_load_style;
OptionValueSP value_sp =
names->GetValueForKey(module_fspec.GetFileNameStrippingExtension());
if (!value_sp)
- return eLazyBoolCalculate;
-
- auto maybe_can_load = value_sp->GetValueAs<bool>();
- if (!maybe_can_load)
- return eLazyBoolCalculate;
+ return default_load_style;
- return *maybe_can_load ? eLazyBoolYes : eLazyBoolNo;
+ return value_sp->GetValueAs<LoadScriptFromSymFile>().value_or(
+ default_load_style);
}
-std::pair<FileSpecList, FileSpecList>
+llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
Platform::LocateExecutableScriptingResourcesFromSafePaths(
Stream &feedback_stream, FileSpec module_spec, const Target &target) {
assert(module_spec);
@@ -199,8 +200,6 @@ Platform::LocateExecutableScriptingResourcesFromSafePaths(
->GetSanitizedScriptingModuleName(
module_spec.GetFileNameStrippingExtension().GetStringRef());
- FileSpecList non_auto_load_files;
- FileSpecList auto_load_files;
FileSpecList paths = Debugger::GetSafeAutoLoadPaths();
// Iterate in reverse so we consider the latest appended path first.
@@ -225,11 +224,9 @@ Platform::LocateExecutableScriptingResourcesFromSafePaths(
orig_script_fspec, script_fspec);
if (FileSystem::Instance().Exists(script_fspec)) {
- LazyBool can_auto_load = CanAutoLoadModule(module_spec, target);
- if (can_auto_load == eLazyBoolYes)
- auto_load_files.Append(script_fspec);
- else if (can_auto_load == eLazyBoolCalculate)
- non_auto_load_files.Append(script_fspec);
+ LoadScriptFromSymFile load_style =
+ Platform::GetScriptLoadStyleForModule(script_fspec, target);
+ file_specs.try_emplace(std::move(script_fspec), load_style);
}
// If we successfully found a directory in a safe auto-load path
@@ -237,7 +234,7 @@ Platform::LocateExecutableScriptingResourcesFromSafePaths(
break;
}
- return {auto_load_files, non_auto_load_files};
+ return file_specs;
}
llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
@@ -247,7 +244,7 @@ Platform::LocateExecutableScriptingResourcesForPlatform(
return empty;
}
-std::pair<FileSpecList, FileSpecList>
+llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
Platform::LocateExecutableScriptingResources(Target *target, Module &module,
Stream &feedback_stream) {
llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> empty;
@@ -257,8 +254,8 @@ Platform::LocateExecutableScriptingResources(Target *target, Module &module,
// Give derived platforms a chance to locate scripting resources.
if (auto fspecs = LocateExecutableScriptingResourcesForPlatform(
target, module, feedback_stream);
- !fspecs.IsEmpty())
- return {{}, fspecs};
+ !fspecs.empty())
+ return fspecs;
const FileSpec &module_spec = module.GetFileSpec();
if (!module_spec)
diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td
index a54c6090fa82a..d74fcd35c690d 100644
--- a/lldb/source/Target/TargetProperties.td
+++ b/lldb/source/Target/TargetProperties.td
@@ -222,7 +222,8 @@ let Definition = "target", Path = "target" in {
Desc<"Enable loading of modules in parallel for the dynamic loader.">;
def AutoLoadScriptsForModules
: Property<"auto-load-scripts-for-modules", "Dictionary">,
- ElementType<"Boolean">,
+ ElementType<"Enum">,
+ EnumValues<"OptionEnumValues(g_load_script_from_sym_file_values)">,
Desc<"A list of module names and whether LLDB will auto-load scripting "
"resources for it from safe paths.">;
}
diff --git a/lldb/unittests/Platform/PlatformTest.cpp b/lldb/unittests/Platform/PlatformTest.cpp
index cea14b5a095c4..c0b7cf1678293 100644
--- a/lldb/unittests/Platform/PlatformTest.cpp
+++ b/lldb/unittests/Platform/PlatformTest.cpp
@@ -226,12 +226,10 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", module_dir);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- ASSERT_EQ(file_specs.GetSize(), 0u);
+ ASSERT_EQ(file_specs.size(), 0u);
}
TEST_F(PlatformLocateSafePathTest,
@@ -254,12 +252,10 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule1.py", module_dir);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- ASSERT_EQ(file_specs.GetSize(), 0u);
+ ASSERT_EQ(file_specs.size(), 0u);
}
TEST_F(PlatformLocateSafePathTest,
@@ -284,13 +280,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("not_a_script.txt", module_dir);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "TestModule.py");
+ EXPECT_EQ(file_specs.size(), 1u);
+
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_EQ(fspec.GetFilename(), "TestModule.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
}
TEST_F(PlatformLocateSafePathTest,
@@ -317,12 +314,10 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", nested_dir);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- EXPECT_EQ(file_specs.GetSize(), 0u);
+ EXPECT_EQ(file_specs.size(), 0u);
}
TEST_F(PlatformLocateSafePathTest,
@@ -378,11 +373,8 @@ TEST_F(PlatformLocateSafePathTest,
FileSpec(path2));
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
-
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
// path1 was the last appended path with a matching directory.
auto [fspec, load_style] = *file_specs.begin();
@@ -398,8 +390,7 @@ TEST_F(PlatformLocateSafePathTest,
FileSpec(path3));
file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp)
- .second;
+ ss, module_fspec, *m_target_sp);
EXPECT_EQ(file_specs.size(), 0u);
@@ -407,8 +398,7 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", path3_module_dir);
file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp)
- .second;
+ ss, module_fspec, *m_target_sp);
EXPECT_EQ(file_specs.size(), 1u);
@@ -439,12 +429,10 @@ TEST_F(PlatformLocateSafePathTest,
ASSERT_TRUE(orig_fspec);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- EXPECT_EQ(file_specs.GetSize(), 0u);
+ EXPECT_EQ(file_specs.size(), 0u);
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because"
@@ -477,14 +465,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule_1_1_1.py", module_dir);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(),
- "TestModule_1_1_1.py");
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_EQ(fspec.GetFilename(), "TestModule_1_1_1.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because"
@@ -513,14 +501,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule_1_1_1.py", module_dir);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
-
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(),
- "TestModule_1_1_1.py");
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
+
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_EQ(fspec.GetFilename(), "TestModule_1_1_1.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
EXPECT_TRUE(ss.GetString().empty());
}
@@ -544,12 +532,10 @@ TEST_F(PlatformLocateSafePathTest,
ASSERT_TRUE(orig_fspec);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- EXPECT_EQ(file_specs.GetSize(), 0u);
+ EXPECT_EQ(file_specs.size(), 0u);
std::string expected = llvm::formatv(
"debug script '{0}' cannot be loaded because 'import.py' "
@@ -581,13 +567,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("_import.py", module_dir);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "_import.py");
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_EQ(fspec.GetFilename(), "_import.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
std::string expected =
llvm::formatv("debug script '{0}' cannot be loaded because 'import.py' "
@@ -616,13 +603,14 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("_import.py", module_dir);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- EXPECT_EQ(file_specs.GetSize(), 1u);
- EXPECT_EQ(file_specs.GetFileSpecAtIndex(0).GetFilename(), "_import.py");
+ EXPECT_EQ(file_specs.size(), 1u);
+
+ auto [fspec, load_style] = *file_specs.begin();
+ EXPECT_EQ(fspec.GetFilename(), "_import.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
EXPECT_TRUE(ss.GetString().empty());
}
@@ -646,12 +634,10 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", inner_dir);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- EXPECT_EQ(file_specs.GetSize(), 0u);
+ EXPECT_EQ(file_specs.size(), 0u);
EXPECT_TRUE(ss.GetString().empty());
}
@@ -680,12 +666,10 @@ TEST_F(PlatformLocateSafePathTest,
CreateFile("TestModule.py", module_dir);
StreamString ss;
- auto [auto_load_spces, file_specs] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(auto_load_spces.GetSize(), 0u);
- EXPECT_EQ(file_specs.GetSize(), 1u);
+ EXPECT_EQ(file_specs.size(), 1u);
EXPECT_TRUE(ss.GetString().empty());
}
@@ -709,14 +693,15 @@ TEST_F(PlatformLocateSafePathTest,
m_target_sp->SetAutoLoadScriptsForModules("TestModule", true);
StreamString ss;
- auto [auto_load_files, non_auto_load_files] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
-
- EXPECT_EQ(auto_load_files.GetSize(), 1u);
- EXPECT_EQ(auto_load_files.GetFileSpecAtIndex(0).GetFilename(),
- "TestModule.py");
- EXPECT_EQ(non_auto_load_files.GetSize(), 0u);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
+
+ auto [fspec, load_style] = *file_specs.begin();
+
+ EXPECT_EQ(fspec.GetFilename(), "TestModule.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
}
TEST_F(PlatformLocateSafePathTest,
@@ -739,12 +724,10 @@ TEST_F(PlatformLocateSafePathTest,
m_target_sp->SetAutoLoadScriptsForModules("TestModule", false);
StreamString ss;
- auto [auto_load_files, non_auto_load_files] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
- EXPECT_EQ(auto_load_files.GetSize(), 0u);
- EXPECT_EQ(non_auto_load_files.GetSize(), 0u);
+ EXPECT_EQ(file_specs.size(), 0);
}
TEST_F(PlatformLocateSafePathTest,
@@ -768,14 +751,15 @@ TEST_F(PlatformLocateSafePathTest,
m_target_sp->SetAutoLoadScriptsForModules("SomeOtherModule", true);
StreamString ss;
- auto [auto_load_files, non_auto_load_files] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_fspec, *m_target_sp);
-
- EXPECT_EQ(auto_load_files.GetSize(), 0u);
- EXPECT_EQ(non_auto_load_files.GetSize(), 1u);
- EXPECT_EQ(non_auto_load_files.GetFileSpecAtIndex(0).GetFilename(),
- "TestModule.py");
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
+
+ auto [fspec, load_style] = *file_specs.begin();
+
+ EXPECT_EQ(fspec.GetFilename(), "TestModule.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
}
TEST_F(PlatformLocateSafePathTest,
@@ -810,27 +794,28 @@ TEST_F(PlatformLocateSafePathTest,
{
StreamString ss;
- auto [auto_load_files, non_auto_load_files] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_a_fspec, *m_target_sp);
-
- EXPECT_EQ(auto_load_files.GetSize(), 1u);
- EXPECT_EQ(auto_load_files.GetFileSpecAtIndex(0).GetFilename(),
- "ModuleA.py");
- EXPECT_EQ(non_auto_load_files.GetSize(), 0u);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_a_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
+
+ auto [fspec, load_style] = *file_specs.begin();
+
+ EXPECT_EQ(fspec.GetFilename(), "ModuleA.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
}
{
StreamString ss;
- auto [auto_load_files, non_auto_load_files] =
- Platform::LocateExecutableScriptingResourcesFromSafePaths(
- ss, module_b_fspec, *m_target_sp);
-
- EXPECT_EQ(auto_load_files.GetSize(), 1u);
- EXPECT_EQ(auto_load_files.GetFileSpecAtIndex(0).GetFilename(),
- "ModuleB.py");
- EXPECT_EQ(non_auto_load_files.GetSize(), 0u);
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_b_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 1u);
+
+ auto [fspec, load_style] = *file_specs.begin();
+
+ EXPECT_EQ(fspec.GetFilename(), "ModuleB.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
}
}
-
#endif // NDEBUG
More information about the lldb-commits
mailing list