[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
Wed Apr 1 00:08:50 PDT 2026
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/188722
>From 12a8e6dc28f00c35b6338ca850c54a3c53758ba0 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/3] [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.
---
.../Plugins/Platform/MacOSX/PlatformDarwin.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index c4865c4664651..0f7475591d5a0 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -256,13 +256,13 @@ PlatformDarwin::LocateExecutableScriptingResourcesFromDSYM(
llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
PlatformDarwin::LocateExecutableScriptingResourcesForPlatform(
Target *target, Module &module, Stream &feedback_stream) {
- llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> empty;
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> file_specs;
if (!target)
- return empty;
+ return file_specs;
// For now only Python scripts supported for auto-loading.
if (target->GetDebugger().GetScriptLanguage() != eScriptLanguagePython)
- return empty;
+ return file_specs;
// NB some extensions might be meaningful and should not be stripped -
// "this.binary.file"
@@ -274,15 +274,15 @@ PlatformDarwin::LocateExecutableScriptingResourcesForPlatform(
const FileSpec &module_spec = module.GetFileSpec();
if (!module_spec)
- return empty;
+ return file_specs;
SymbolFile *symfile = module.GetSymbolFile();
if (!symfile)
- return empty;
+ return file_specs;
ObjectFile *objfile = symfile->GetObjectFile();
if (!objfile)
- return empty;
+ return file_specs;
const FileSpec &symfile_spec = objfile->GetFileSpec();
if (symfile_spec &&
@@ -292,7 +292,7 @@ PlatformDarwin::LocateExecutableScriptingResourcesForPlatform(
return LocateExecutableScriptingResourcesFromDSYM(
feedback_stream, module_spec, *target, symfile_spec);
- return empty;
+ return file_specs;
}
Status PlatformDarwin::ResolveSymbolFile(Target &target,
>From 3c3e0fd2c9ef745b22c3f7565a3b5bc0d76644f4 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/3] [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 | 7 +
lldb/include/lldb/Target/Target.h | 5 +
lldb/source/Core/Module.cpp | 3 +-
.../Platform/MacOSX/PlatformDarwin.cpp | 5 +-
lldb/source/Target/Platform.cpp | 29 +++-
lldb/source/Target/Target.cpp | 14 ++
lldb/source/Target/TargetProperties.td | 6 +
.../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 | 146 ++++++++++++++++++
12 files changed, 327 insertions(+), 6 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..39c5466c95330 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -1086,6 +1086,13 @@ class Platform : public PluginInterface {
const ScriptInterpreter::SanitizedScriptingModuleName &sanitized_name,
const FileSpec &original_fspec, const FileSpec &fspec);
+ /// Returns the \c LoadScriptFromSymFile of scripting resource associated
+ /// with the specified module \c FileSpec. If the load style wasn't explicitly
+ /// set for a module, returns the target-wide default.
+ static LoadScriptFromSymFile
+ GetScriptLoadStyleForModule(const FileSpec &module_fspec,
+ const Target &target);
+
private:
typedef std::function<Status(const ModuleSpec &)> ModuleResolver;
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 77b8f04a4b3b8..66d79ad4dd277 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -278,6 +278,11 @@ class TargetProperties : public Properties {
bool GetDebugUtilityExpression() const;
+ OptionValueDictionary *GetAutoLoadScriptsForModules() const;
+
+ void SetAutoLoadScriptsForModules(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 808c8a347e9b2..c81912fa35a43 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1490,7 +1490,8 @@ To run all discovered debug scripts in this session:
debugger.GetID());
// clang-format on
- return false;
+ // TODO: test this
+ continue;
}
LLDB_LOG(log, "Auto-loading {0}", scripting_fspec.GetPath());
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 0f7475591d5a0..c71a8956013d8 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 55eaa88b562d4..33b3805780f0e 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"
@@ -40,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"
@@ -157,6 +159,25 @@ Status Platform::GetFileWithUUID(const FileSpec &platform_file,
return Status();
}
+LoadScriptFromSymFile
+Platform::GetScriptLoadStyleForModule(const FileSpec &module_fspec,
+ const Target &target) {
+ LoadScriptFromSymFile default_load_style =
+ target.GetLoadScriptFromSymbolFile();
+
+ OptionValueDictionary *names = target.GetAutoLoadScriptsForModules();
+ if (!names)
+ return default_load_style;
+
+ OptionValueSP value_sp =
+ names->GetValueForKey(module_fspec.GetFileNameStrippingExtension());
+ if (!value_sp)
+ return default_load_style;
+
+ return value_sp->GetValueAs<LoadScriptFromSymFile>().value_or(
+ default_load_style);
+}
+
llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
Platform::LocateExecutableScriptingResourcesFromSafePaths(
Stream &feedback_stream, FileSpec module_spec, const Target &target) {
@@ -198,9 +219,11 @@ 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)) {
+ 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
// stop looking at any other paths.
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 2a3832225f9b7..249657eb04a21 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -5278,6 +5278,20 @@ void TargetProperties::SetDebugUtilityExpression(bool debug) {
SetPropertyAtIndex(idx, debug);
}
+OptionValueDictionary *TargetProperties::GetAutoLoadScriptsForModules() const {
+ return m_collection_sp->GetPropertyAtIndexAsOptionValueDictionary(
+ ePropertyAutoLoadScriptsForModules);
+}
+
+void TargetProperties::SetAutoLoadScriptsForModules(llvm::StringRef module_name,
+ bool should_load) {
+ OptionValueDictionary *dict = GetAutoLoadScriptsForModules();
+ 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..d74fcd35c690d 100644
--- a/lldb/source/Target/TargetProperties.td
+++ b/lldb/source/Target/TargetProperties.td
@@ -220,6 +220,12 @@ 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 AutoLoadScriptsForModules
+ : Property<"auto-load-scripts-for-modules", "Dictionary">,
+ 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.">;
}
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..7154d52e8f6a2
--- /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-scripts-for-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-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
+
+#--- 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..d26c574ff2d5c
--- /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-scripts-for-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-scripts-for-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..3213ae61558dd
--- /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-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.
+
+# 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-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
+
+#--- 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..f1f2932cac55b
--- /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-scripts-for-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-scripts-for-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..c0b7cf1678293 100644
--- a/lldb/unittests/Platform/PlatformTest.cpp
+++ b/lldb/unittests/Platform/PlatformTest.cpp
@@ -672,4 +672,150 @@ TEST_F(PlatformLocateSafePathTest,
EXPECT_EQ(file_specs.size(), 1u);
EXPECT_TRUE(ss.GetString().empty());
}
+
+TEST_F(PlatformLocateSafePathTest,
+ LocateScriptingResourcesFromSafePaths_AutoLoadModule_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(
+ 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->SetAutoLoadScriptsForModules("TestModule", true);
+
+ 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.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
+}
+
+TEST_F(PlatformLocateSafePathTest,
+ LocateScriptingResourcesFromSafePaths_AutoLoadModule_False) {
+ // 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));
+
+ 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->SetAutoLoadScriptsForModules("TestModule", false);
+
+ StreamString ss;
+ auto file_specs = Platform::LocateExecutableScriptingResourcesFromSafePaths(
+ ss, module_fspec, *m_target_sp);
+
+ EXPECT_EQ(file_specs.size(), 0);
+}
+
+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->SetAutoLoadScriptsForModules("SomeOtherModule", true);
+
+ 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.py");
+ EXPECT_EQ(load_style, m_target_sp->GetLoadScriptFromSymbolFile());
+}
+
+TEST_F(PlatformLocateSafePathTest,
+ LocateScriptingResourcesFromSafePaths_AutoLoadModule_Multiple) {
+ // 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));
+
+ // 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->SetAutoLoadScriptsForModules("ModuleA", true);
+ m_target_sp->SetAutoLoadScriptsForModules("ModuleB", true);
+
+ {
+ StreamString ss;
+ 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 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
>From c6ec21667bfe787839794443a911a808d9985303 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 1 Apr 2026 08:08:37 +0100
Subject: [PATCH 3/3] fixup! revert mismerge
---
.../Plugins/Platform/MacOSX/PlatformDarwin.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index c71a8956013d8..200bf7c222935 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -257,13 +257,13 @@ PlatformDarwin::LocateExecutableScriptingResourcesFromDSYM(
llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile>
PlatformDarwin::LocateExecutableScriptingResourcesForPlatform(
Target *target, Module &module, Stream &feedback_stream) {
- llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> file_specs;
+ llvm::SmallDenseMap<FileSpec, LoadScriptFromSymFile> empty;
if (!target)
- return file_specs;
+ return empty;
// For now only Python scripts supported for auto-loading.
if (target->GetDebugger().GetScriptLanguage() != eScriptLanguagePython)
- return file_specs;
+ return empty;
// NB some extensions might be meaningful and should not be stripped -
// "this.binary.file"
@@ -275,15 +275,15 @@ PlatformDarwin::LocateExecutableScriptingResourcesForPlatform(
const FileSpec &module_spec = module.GetFileSpec();
if (!module_spec)
- return file_specs;
+ return empty;
SymbolFile *symfile = module.GetSymbolFile();
if (!symfile)
- return file_specs;
+ return empty;
ObjectFile *objfile = symfile->GetObjectFile();
if (!objfile)
- return file_specs;
+ return empty;
const FileSpec &symfile_spec = objfile->GetFileSpec();
if (symfile_spec &&
@@ -293,7 +293,7 @@ PlatformDarwin::LocateExecutableScriptingResourcesForPlatform(
return LocateExecutableScriptingResourcesFromDSYM(
feedback_stream, module_spec, *target, symfile_spec);
- return file_specs;
+ return empty;
}
Status PlatformDarwin::ResolveSymbolFile(Target &target,
More information about the lldb-commits
mailing list