aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces
diff options
context:
space:
mode:
authorMed Ismail Bennani <ismail@bennani.ma>2025-12-01 14:45:54 -0800
committerGitHub <noreply@github.com>2025-12-01 14:45:54 -0800
commitb7c358c44af3cda2b731f6bb94f6d765350017a4 (patch)
tree963c9f73fc1603cfb6ba4e23b990ed6f53eb57f9 /lldb/source/Plugins/ScriptInterpreter/Python/Interfaces
parent229dca66df6d0f9253273565d82972fd1787bd4a (diff)
downloadllvm-b7c358c44af3cda2b731f6bb94f6d765350017a4.tar.gz
llvm-b7c358c44af3cda2b731f6bb94f6d765350017a4.tar.bz2
llvm-b7c358c44af3cda2b731f6bb94f6d765350017a4.zip
[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 <ismail@bennani.ma>
Diffstat (limited to 'lldb/source/Plugins/ScriptInterpreter/Python/Interfaces')
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
index 5f5665c49577..23c56610124a 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h
@@ -55,6 +55,62 @@ public:
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 {