Skip to content

Conversation

@medismailben
Copy link
Member

This adds a new virtual method GetScriptedModulePath() to ScriptedInterface that allows retrieving the file path of the Python module containing the scripted object implementation.

The Python implementation acquires the GIL and walks through the object's __class__.__module__ to find the module's __file__ attribute. This will be used by ScriptedFrame to populate the module and compile unit for frames pointing to Python source files.

@llvmbot
Copy link
Member

llvmbot commented Dec 1, 2025

@llvm/pr-subscribers-lldb

Author: Med Ismail Bennani (medismailben)

Changes

This adds a new virtual method GetScriptedModulePath() to ScriptedInterface that allows retrieving the file path of the Python module containing the scripted object implementation.

The Python implementation acquires the GIL and walks through the object's __class__.__module__ to find the module's __file__ attribute. This will be used by ScriptedFrame to populate the module and compile unit for frames pointing to Python source files.


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

2 Files Affected:

  • (modified) lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h (+4)
  • (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h (+56)
diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
index a3dc52c435561..88e4f6813ce0c 100644
--- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
+++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
@@ -39,6 +39,10 @@ class ScriptedInterface {
   virtual llvm::SmallVector<AbstractMethodRequirement>
   GetAbstractMethodRequirements() const = 0;
 
+  virtual llvm::Expected<std::string> GetScriptedModulePath() {
+    return llvm::make_error<UnimplementedError>();
+  }
+
   llvm::SmallVector<llvm::StringLiteral> const GetAbstractMethods() const {
     llvm::SmallVector<llvm::StringLiteral> abstract_methods;
     llvm::transform(GetAbstractMethodRequirements(), abstract_methods.begin(),
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index cdda66abc562b..72cc5d55a6d26 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -55,6 +55,62 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
     std::variant<std::monostate, InvalidArgumentCountPayload> payload;
   };
 
+  llvm::Expected<std::string> GetScriptedModulePath() override {
+    if (!m_object_instance_sp)
+      return llvm::createStringError("Scripted Interface has invalid object.");
+
+    using namespace python;
+    using Locker = ScriptInterpreterPythonImpl::Locker;
+
+    Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                   Locker::FreeLock);
+
+    PythonObject py_obj =
+        PythonObject(PyRefType::Borrowed,
+                     static_cast<PyObject *>(m_object_instance_sp->GetValue()));
+
+    if (!py_obj.IsAllocated())
+      return llvm::createStringError(
+          "Scripted Interface has invalid python object.");
+
+    PythonObject py_obj_class = py_obj.GetAttributeValue("__class__");
+    if (!py_obj_class.IsValid())
+      return llvm::createStringError(
+          "Scripted Interface python object is missing '__class__' attribute.");
+
+    PythonObject py_obj_module = py_obj_class.GetAttributeValue("__module__");
+    if (!py_obj_module.IsValid())
+      return llvm::createStringError(
+          "Scripted Interface python object '__class__' is missing "
+          "'__module__' attribute.");
+
+    PythonString py_obj_module_str = py_obj_module.Str();
+    if (!py_obj_module_str.IsValid())
+      return llvm::createStringError(
+          "Scripted Interface python object '__class__.__module__' attribute "
+          "is not a string.");
+
+    llvm::StringRef py_obj_module_str_ref = py_obj_module_str.GetString();
+    PythonModule py_module = PythonModule::AddModule(py_obj_module_str_ref);
+    if (!py_module.IsValid())
+      return llvm::createStringError("Failed to import '%s' module.",
+                                     py_obj_module_str_ref.data());
+
+    PythonObject py_module_file = py_module.GetAttributeValue("__file__");
+    if (!py_module_file.IsValid())
+      return llvm::createStringError(
+          "Module '%s' is missing '__file__' attribute.",
+          py_obj_module_str_ref.data());
+
+    PythonString py_module_file_str = py_module_file.Str();
+    if (!py_module_file_str.IsValid())
+      return llvm::createStringError(
+          "Module '%s.__file__' attribute is not a string.",
+          py_obj_module_str_ref.data());
+
+    return py_obj_module_str.GetString().str();
+  }
+
   llvm::Expected<std::map<llvm::StringLiteral, AbstractMethodCheckerPayload>>
   CheckAbstractMethodImplementation(
       const python::PythonDictionary &class_dict) const {

@medismailben medismailben force-pushed the get-scripted-module-path branch from 2f86bcc to 84aef15 Compare December 1, 2025 22:18
@github-actions
Copy link

github-actions bot commented Dec 1, 2025

🐧 Linux x64 Test Results

  • 33206 tests passed
  • 497 tests skipped

✅ The build succeeded and all tests passed.

This adds a new virtual method `GetScriptedModulePath()` to `ScriptedInterface`
that allows retrieving the file path of the Python module containing the
scripted object implementation.

The Python implementation acquires the GIL and walks through the object's
`__class__.__module__` to find the module's `__file__` attribute. This will be
used by ScriptedFrame to populate the module and compile unit for frames
pointing to Python source files.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
@medismailben medismailben force-pushed the get-scripted-module-path branch from 84aef15 to 3759044 Compare December 1, 2025 22:38
@medismailben medismailben merged commit b7c358c into llvm:main Dec 1, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants