Skip to content

Commit b7c358c

Browse files
authored
[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]>
1 parent 229dca6 commit b7c358c

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ class ScriptedInterface {
3939
virtual llvm::SmallVector<AbstractMethodRequirement>
4040
GetAbstractMethodRequirements() const = 0;
4141

42+
virtual llvm::Expected<FileSpec> GetScriptedModulePath() {
43+
return llvm::make_error<UnimplementedError>();
44+
}
45+
4246
llvm::SmallVector<llvm::StringLiteral> const GetAbstractMethods() const {
4347
llvm::SmallVector<llvm::StringLiteral> abstract_methods;
4448
llvm::transform(GetAbstractMethodRequirements(), abstract_methods.begin(),

lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,62 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
5555
std::variant<std::monostate, InvalidArgumentCountPayload> payload;
5656
};
5757

58+
llvm::Expected<FileSpec> GetScriptedModulePath() override {
59+
using namespace python;
60+
using Locker = ScriptInterpreterPythonImpl::Locker;
61+
62+
Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
63+
Locker::FreeLock);
64+
65+
if (!m_object_instance_sp)
66+
return llvm::createStringError("scripted Interface has invalid object");
67+
68+
PythonObject py_obj =
69+
PythonObject(PyRefType::Borrowed,
70+
static_cast<PyObject *>(m_object_instance_sp->GetValue()));
71+
72+
if (!py_obj.IsAllocated())
73+
return llvm::createStringError(
74+
"scripted Interface has invalid python object");
75+
76+
PythonObject py_obj_class = py_obj.GetAttributeValue("__class__");
77+
if (!py_obj_class.IsValid())
78+
return llvm::createStringError(
79+
"scripted Interface python object is missing '__class__' attribute");
80+
81+
PythonObject py_obj_module = py_obj_class.GetAttributeValue("__module__");
82+
if (!py_obj_module.IsValid())
83+
return llvm::createStringError(
84+
"scripted Interface python object '__class__' is missing "
85+
"'__module__' attribute");
86+
87+
PythonString py_obj_module_str = py_obj_module.Str();
88+
if (!py_obj_module_str.IsValid())
89+
return llvm::createStringError(
90+
"scripted Interface python object '__class__.__module__' attribute "
91+
"is not a string");
92+
93+
llvm::StringRef py_obj_module_str_ref = py_obj_module_str.GetString();
94+
PythonModule py_module = PythonModule::AddModule(py_obj_module_str_ref);
95+
if (!py_module.IsValid())
96+
return llvm::createStringError("failed to import '%s' module",
97+
py_obj_module_str_ref.data());
98+
99+
PythonObject py_module_file = py_module.GetAttributeValue("__file__");
100+
if (!py_module_file.IsValid())
101+
return llvm::createStringError(
102+
"module '%s' is missing '__file__' attribute",
103+
py_obj_module_str_ref.data());
104+
105+
PythonString py_module_file_str = py_module_file.Str();
106+
if (!py_module_file_str.IsValid())
107+
return llvm::createStringError(
108+
"module '%s.__file__' attribute is not a string",
109+
py_obj_module_str_ref.data());
110+
111+
return FileSpec(py_obj_module_str.GetString());
112+
}
113+
58114
llvm::Expected<std::map<llvm::StringLiteral, AbstractMethodCheckerPayload>>
59115
CheckAbstractMethodImplementation(
60116
const python::PythonDictionary &class_dict) const {

0 commit comments

Comments
 (0)