Author: Med Ismail Bennani
Date: 2025-12-01T14:45:54-08:00
New Revision: b7c358c44af3cda2b731f6bb94f6d765350017a4

URL: 
https://github.com/llvm/llvm-project/commit/b7c358c44af3cda2b731f6bb94f6d765350017a4
DIFF: 
https://github.com/llvm/llvm-project/commit/b7c358c44af3cda2b731f6bb94f6d765350017a4.diff

LOG: [lldb/ScriptInterpreter] Add a way to retrieve script module file path 
(#170202)

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 <[email protected]>

Added: 
    

Modified: 
    lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
    
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h 
b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h
index a3dc52c435561..8ace90927b582 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<FileSpec> 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 5f5665c495770..23c56610124a6 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<FileSpec> GetScriptedModulePath() override {
+    using namespace python;
+    using Locker = ScriptInterpreterPythonImpl::Locker;
+
+    Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                   Locker::FreeLock);
+
+    if (!m_object_instance_sp)
+      return llvm::createStringError("scripted Interface has invalid object");
+
+    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 FileSpec(py_obj_module_str.GetString());
+  }
+
   llvm::Expected<std::map<llvm::StringLiteral, AbstractMethodCheckerPayload>>
   CheckAbstractMethodImplementation(
       const python::PythonDictionary &class_dict) const {


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to