[Lldb-commits] [lldb] [lldb][Module] Make eLoadScriptFromSymFileWarn behave as a "dry-run" (PR #189943)

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Wed Apr 1 04:39:16 PDT 2026


https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/189943

This patch is a follow-up to https://github.com/llvm/llvm-project/pull/189444#issuecomment-4165226875

We want `eLoadScriptFromSymFileWarn` to be a "dry-run" mode which warns but all possible module loads but doesn't actually load them. To do so, this patch removes the short-circuit in the current module loading loop.

The previous warning is verbose and contains instructions that don't need to be printed for every module. So this patch ensures LLDB only prints the verbose warning once per debugger-session. The script paths that would have been loaded are accumulated and printed at the end of the function. We `return false` to preserve the previous semantics of `LoadScriptingResourceInTarget`.

Eventually we want the warning to also indicate whether the module in consideration is a safe/trusted module or not but I wanted to keep that for a separate PR.

>From dc91f5415f30c870b6e1d04a94102ccd0d6a399a Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 1 Apr 2026 09:32:13 +0100
Subject: [PATCH] [lldb][Module] Make eLoadScriptFromSymFileWarn behave as a
 "dry-run"

This patch is a follow-up to https://github.com/llvm/llvm-project/pull/189444#issuecomment-4165226875

We want `eLoadScriptFromSymFileWarn` to be a "dry-run" mode which warns but all possible module loads but doesn't actually load them. To do so, this patch removes the short-circuit in the current module loading loop.

The previous warning is verbose and contains instructions that don't need to be printed for every module. So this patch ensures LLDB only prints the verbose warning once per debugger-session. The script paths that would have been loaded are accumulated and printed at the end of the function. We `return false` to preserve the previous semantics of `LoadScriptingResourceInTarget`.

Eventually we want the warning to also indicate whether the module in consideration is a safe/trusted module or not but I wanted to keep that for a separate PR.
---
 lldb/source/Core/Module.cpp                   | 26 +++++++++----
 .../dsym-python-script-name-warnings.test     |  2 +-
 .../AutoLoad/Darwin/dsym-python-script.test   |  4 +-
 .../Darwin/dsym-warn-multiple-modules.test    | 38 ++++++++++++++++++
 .../UNIX/safe-path-warn-multiple-modules.test | 39 +++++++++++++++++++
 5 files changed, 98 insertions(+), 11 deletions(-)
 create mode 100644 lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-warn-multiple-modules.test
 create mode 100644 lldb/test/Shell/Platform/AutoLoad/UNIX/safe-path-warn-multiple-modules.test

diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 808c8a347e9b2..3e30e1bb63121 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1466,6 +1466,8 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error) {
   if (!feedback_stream.Empty())
     debugger.ReportWarning(feedback_stream.GetString().str(), debugger.GetID());
 
+  llvm::SmallVector<std::string> warned_modules;
+
   for (const auto &[scripting_fspec, load_style] : file_specs) {
     if (load_style == eLoadScriptFromSymFileFalse)
       continue;
@@ -1474,23 +1476,22 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error) {
       continue;
 
     if (load_style == eLoadScriptFromSymFileWarn) {
+      static std::once_flag s_warn_once;
       // clang-format off
       debugger.ReportWarning(
-          llvm::formatv(
-R"('{0}' contains a debug script. To run this script in this debug session:
+R"(Found executable debug scripts. To run this script in this debug session:
 
-    command script import "{1}"
+    command script import "/path/to/script.py"
 
 To run all discovered debug scripts in this session:
 
     settings set target.load-script-from-symbol-file true
-)",
-              GetFileSpec().GetFileNameStrippingExtension(),
-              scripting_fspec.GetPath()),
-          debugger.GetID());
+)", debugger.GetID(), &s_warn_once);
       // clang-format on
 
-      return false;
+      warned_modules.emplace_back(scripting_fspec.GetPath());
+
+      continue;
     }
 
     LLDB_LOG(log, "Auto-loading {0}", scripting_fspec.GetPath());
@@ -1503,6 +1504,15 @@ To run all discovered debug scripts in this session:
     }
   }
 
+  if (!warned_modules.empty()) {
+    debugger.ReportWarning(
+        llvm::formatv(
+            "Following debug scripts were detected but not loaded:\n{0}",
+            llvm::join(warned_modules, "\n")),
+        debugger.GetID());
+    return false;
+  }
+
   return true;
 }
 
diff --git a/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-python-script-name-warnings.test b/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-python-script-name-warnings.test
index 9c84045d75932..a1556096ed342 100644
--- a/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-python-script-name-warnings.test
+++ b/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-python-script-name-warnings.test
@@ -33,7 +33,7 @@
 
 ## Also confirm that the warning message about auto-loading scripts is printed afterwards.
 
-# CHECK-REMOVE: warning: 'Test-Module2' contains a debug script. To run this script in this
+# CHECK-REMOVE: warning: Found executable debug scripts. To run this script in this debug session
 
 #--- main.c
 int main() { return 0; }
diff --git a/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-python-script.test b/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-python-script.test
index d19199f7e55be..0e4cb37f4fcd4 100644
--- a/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-python-script.test
+++ b/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-python-script.test
@@ -23,9 +23,9 @@
 # RUN:   -o 'target create %t/TestModule.out' 2>&1 \
 # RUN:   | FileCheck %s --implicit-check-not=warning --check-prefix=CHECK-LOADED
 
-# CHECK-WARN:      warning: 'TestModule' contains a debug script. To run this script in this debug session:
+# CHECK-WARN:      warning: Found executable debug scripts. To run this script in this debug session:
 # CHECK-WARN-EMPTY:
-# CHECK-WARN-NEXT:{{^}}    command script import "{{.*}}/TestModule.out.dSYM/Contents/Resources/Python/TestModule.py"
+# CHECK-WARN-NEXT:{{^}}    command script import "/path/to/script.py"
 # CHECK-WARN-EMPTY:
 # CHECK-WARN-NEXT: To run all discovered debug scripts in this session:
 # CHECK-WARN-EMPTY:
diff --git a/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-warn-multiple-modules.test b/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-warn-multiple-modules.test
new file mode 100644
index 0000000000000..508d0999d609d
--- /dev/null
+++ b/lldb/test/Shell/Platform/AutoLoad/Darwin/dsym-warn-multiple-modules.test
@@ -0,0 +1,38 @@
+# REQUIRES: python, system-darwin
+#
+# Test that when load-script-from-symbol-file is set to 'warn', LLDB emits a
+# warning for dSYM scripts without executing them. Verify that it doesn't
+# abort early by loading a second module whose dSYM script should also trigger
+# a warning.
+
+# RUN: split-file %s %t
+# RUN: %clang_host -g %t/main.c -o %t/TestModule.out
+# RUN: %clang_host -g %t/main.c -o %t/TestModule2.out
+# RUN: mkdir -p %t/TestModule.out.dSYM/Contents/Resources/Python
+# RUN: mkdir -p %t/TestModule2.out.dSYM/Contents/Resources/Python
+
+# RUN: cp %t/dsym_script.py %t/TestModule.out.dSYM/Contents/Resources/Python/TestModule.py
+# RUN: cp %t/dsym_script2.py %t/TestModule2.out.dSYM/Contents/Resources/Python/TestModule2.py
+# RUN: %lldb -b \
+# RUN:   -o 'settings set target.load-script-from-symbol-file warn' \
+# RUN:   -o 'target create %t/TestModule.out' \
+# RUN:   -o 'target modules add %t/TestModule2.out' 2>&1 \
+# RUN:   | FileCheck %s --implicit-check-not=DSYM_SCRIPT --implicit-check-not=DSYM_SCRIPT2
+
+# CHECK-COUNT-1: warning: Found executable debug scripts. To run this script in this debug session
+# CHECK:      Following debug scripts were detected but not loaded:
+# CHECK-DAG: {{.*}}/TestModule.out.dSYM/Contents/Resources/Python/TestModule.py
+# CHECK-DAG: {{.*}}/TestModule2.out.dSYM/Contents/Resources/Python/TestModule2.py
+
+#--- main.c
+int main() { return 0; }
+
+#--- dsym_script.py
+import sys
+def __lldb_init_module(debugger, internal_dict):
+    print("DSYM_SCRIPT", file=sys.stderr)
+
+#--- dsym_script2.py
+import sys
+def __lldb_init_module(debugger, internal_dict):
+    print("DSYM_SCRIPT2", file=sys.stderr)
diff --git a/lldb/test/Shell/Platform/AutoLoad/UNIX/safe-path-warn-multiple-modules.test b/lldb/test/Shell/Platform/AutoLoad/UNIX/safe-path-warn-multiple-modules.test
new file mode 100644
index 0000000000000..ca75cfd1e0bbb
--- /dev/null
+++ b/lldb/test/Shell/Platform/AutoLoad/UNIX/safe-path-warn-multiple-modules.test
@@ -0,0 +1,39 @@
+# REQUIRES: python, asserts, !system-windows
+#
+# Test that when load-script-from-symbol-file is set to 'warn', LLDB emits a
+# warning for safe-path scripts without executing them. Verify that it doesn't
+# abort early by loading a second module whose script should also trigger a
+# warning.
+
+# RUN: split-file %s %t
+# RUN: %clang_host %t/main.c -o %t/TestModule.out
+# RUN: %clang_host %t/main.c -o %t/TestModule2.out
+# RUN: mkdir -p %t/safe-path/TestModule
+# RUN: mkdir -p %t/safe-path/TestModule2
+
+# RUN: cp %t/script.py %t/safe-path/TestModule/TestModule.py
+# RUN: cp %t/script2.py %t/safe-path/TestModule2/TestModule2.py
+# 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 'target create %t/TestModule.out' \
+# RUN:   -o 'target modules add %t/TestModule2.out' 2>&1 \
+# RUN:   | FileCheck %s --implicit-check-not=SCRIPT_LOADED --implicit-check-not=SCRIPT2_LOADED
+
+# CHECK-COUNT-1: warning: Found executable debug scripts. To run this script in this debug session
+# CHECK:      Following debug scripts were detected but not loaded:
+# CHECK-DAG: {{.*}}/safe-path/TestModule/TestModule.py
+# CHECK-DAG: {{.*}}/safe-path/TestModule2/TestModule2.py
+
+#--- main.c
+int main() { return 0; }
+
+#--- script.py
+import sys
+def __lldb_init_module(debugger, internal_dict):
+    print("SCRIPT_LOADED", file=sys.stderr)
+
+#--- script2.py
+import sys
+def __lldb_init_module(debugger, internal_dict):
+    print("SCRIPT2_LOADED", file=sys.stderr)



More information about the lldb-commits mailing list