================ @@ -0,0 +1,278 @@ +//===-- ScriptedSymbolLocatorPythonInterface.cpp +//---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/Config.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Utility/Log.h" +#include "lldb/lldb-enumerations.h" + +#if LLDB_ENABLE_PYTHON + +// clang-format off +// LLDB Python header must be included first +#include "../lldb-python.h" +// clang-format on + +#include "../SWIGPythonBridge.h" +#include "../ScriptInterpreterPythonImpl.h" +#include "ScriptedSymbolLocatorPythonInterface.h" + +#include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBModuleSpec.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::python; +using Locker = ScriptInterpreterPythonImpl::Locker; + +ScriptedSymbolLocatorPythonInterface::ScriptedSymbolLocatorPythonInterface( + ScriptInterpreterPythonImpl &interpreter) + : ScriptedSymbolLocatorInterface(), ScriptedPythonInterface(interpreter) {} + +llvm::Expected<StructuredData::GenericSP> +ScriptedSymbolLocatorPythonInterface::CreatePluginObject( + const llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) { + ExecutionContextRefSP exe_ctx_ref_sp = + std::make_shared<ExecutionContextRef>(exe_ctx); + StructuredDataImpl sd_impl(args_sp); + return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj, + exe_ctx_ref_sp, sd_impl); +} + +/// Helper to convert an internal ModuleSpec to a Python SBModuleSpec object. +/// Must be called with the GIL held. +static PythonObject ToSWIGModuleSpec(const ModuleSpec &module_spec) { + // Build an SBModuleSpec using public API setters since the constructor + // from ModuleSpec is private. + SBModuleSpec sb_module_spec; + + const UUID &uuid = module_spec.GetUUID(); + if (uuid.IsValid()) + sb_module_spec.SetUUIDBytes(uuid.GetBytes().data(), uuid.GetBytes().size()); + + const FileSpec &file = module_spec.GetFileSpec(); + if (file) + sb_module_spec.SetFileSpec(SBFileSpec(file.GetPath().c_str(), false)); + + const FileSpec &platform_file = module_spec.GetPlatformFileSpec(); + if (platform_file) + sb_module_spec.SetPlatformFileSpec( + SBFileSpec(platform_file.GetPath().c_str(), false)); + + const FileSpec &symbol_file = module_spec.GetSymbolFileSpec(); + if (symbol_file) + sb_module_spec.SetSymbolFileSpec( + SBFileSpec(symbol_file.GetPath().c_str(), false)); + + const ArchSpec &arch = module_spec.GetArchitecture(); + if (arch.IsValid()) + sb_module_spec.SetTriple(arch.GetTriple().getTriple().c_str()); + + ConstString object_name = module_spec.GetObjectName(); + if (object_name) + sb_module_spec.SetObjectName(object_name.GetCString()); + + sb_module_spec.SetObjectOffset(module_spec.GetObjectOffset()); + sb_module_spec.SetObjectSize(module_spec.GetObjectSize()); + + return SWIGBridge::ToSWIGWrapper( + std::make_unique<SBModuleSpec>(sb_module_spec)); +} + +/// Helper to convert an internal FileSpec to a Python SBFileSpec object. +/// Must be called with the GIL held. +static PythonObject ToSWIGFileSpec(const FileSpec &file_spec) { + return SWIGBridge::ToSWIGWrapper( + std::make_unique<SBFileSpec>(file_spec.GetPath().c_str(), false)); +} + +std::optional<ModuleSpec> +ScriptedSymbolLocatorPythonInterface::LocateExecutableObjectFile( + const ModuleSpec &module_spec, Status &error) { + if (!m_object_instance_sp) + return {}; + + // Acquire the GIL before creating any Python objects. + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); + + PythonObject implementor(PyRefType::Borrowed, + (PyObject *)m_object_instance_sp->GetValue()); + if (!implementor.IsAllocated()) + return {}; + + PythonObject py_module_spec = ToSWIGModuleSpec(module_spec); + + auto expected = + implementor.CallMethod("locate_executable_object_file", py_module_spec); + if (!expected) { + // Consume the PythonException while the GIL is held. Converting to string + // forces PythonException destruction before the GIL is released. + std::string msg = llvm::toString(expected.takeError()); + error = Status(msg); + return {}; + } + + PythonObject py_return = std::move(*expected); + if (!py_return.IsAllocated() || py_return.IsNone()) + return {}; + + auto obj = py_return.CreateStructuredObject(); + if (!obj) + return {}; ---------------- rchamala wrote:
I thought of using Dispatch, but the entities are not supported for FileSpec, ModuleSpec. I had to add logic there just to support my usecase, instead directly used GIL to resolve my usecase. Do you recommend making changes to dispatch and then use it or current design is fine ? https://github.com/llvm/llvm-project/pull/181334 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
