mib created this revision.
mib added reviewers: JDevlieghere, jingham, bulbazord.
mib added a project: LLDB.
Herald added a project: All.
mib requested review of this revision.
Herald added a subscriber: lldb-commits.

This patch aims to consolidate the OperatingSystem scripting affordance
by introducing a stable interface that conforms to the
Scripted{,Python}Interface.

This unify the way we call into python methods from lldb while
also improving its capabilities by allowing us to pass lldb_private
objects are arguments.

Signed-off-by: Med Ismail Bennani <ism...@bennani.ma>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D159314

Files:
  lldb/bindings/python/python-wrapper.swig
  lldb/bindings/python/python.swig
  lldb/include/lldb/Interpreter/Interfaces/OperatingSystemInterface.h
  lldb/include/lldb/Interpreter/ScriptInterpreter.h
  lldb/include/lldb/lldb-forward.h
  lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
  lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
  lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
  
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
  
lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h

Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -134,24 +134,9 @@
 
   lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override;
 
-  StructuredData::GenericSP
-  OSPlugin_CreatePluginObject(const char *class_name,
-                              lldb::ProcessSP process_sp) override;
-
-  StructuredData::DictionarySP
-  OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
   lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
 
-  StructuredData::ArraySP
-  OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override;
-
-  StructuredData::StringSP
-  OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
-                               lldb::tid_t thread_id) override;
-
-  StructuredData::DictionarySP
-  OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
-                        lldb::tid_t tid, lldb::addr_t context) override;
+  lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override;
 
   StructuredData::ObjectSP
   LoadPluginModule(const FileSpec &file_spec,
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -14,6 +14,7 @@
 // LLDB Python header must be included first
 #include "lldb-python.h"
 
+#include "Interfaces/OperatingSystemPythonInterface.h"
 #include "Interfaces/ScriptedPlatformPythonInterface.h"
 #include "Interfaces/ScriptedProcessPythonInterface.h"
 #include "Interfaces/ScriptedThreadPythonInterface.h"
@@ -1521,6 +1522,11 @@
   return std::make_shared<ScriptedThreadPythonInterface>(*this);
 }
 
+OperatingSystemInterfaceSP
+ScriptInterpreterPythonImpl::CreateOperatingSystemInterface() {
+  return std::make_shared<OperatingSystemPythonInterface>(*this);
+}
+
 StructuredData::ObjectSP
 ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject(
     ScriptObject obj) {
@@ -1532,159 +1538,6 @@
   return py_obj.CreateStructuredObject();
 }
 
-StructuredData::GenericSP
-ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject(
-    const char *class_name, lldb::ProcessSP process_sp) {
-  if (class_name == nullptr || class_name[0] == '\0')
-    return StructuredData::GenericSP();
-
-  if (!process_sp)
-    return StructuredData::GenericSP();
-
-  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-  PythonObject ret_val = SWIGBridge::LLDBSWIGPythonCreateOSPlugin(
-      class_name, m_dictionary_name.c_str(), process_sp);
-
-  return StructuredData::GenericSP(
-      new StructuredPythonObject(std::move(ret_val)));
-}
-
-StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_RegisterInfo(
-    StructuredData::ObjectSP os_plugin_object_sp) {
-  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-
-  if (!os_plugin_object_sp)
-    return {};
-
-  StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
-  if (!generic)
-    return {};
-
-  PythonObject implementor(PyRefType::Borrowed,
-                           (PyObject *)generic->GetValue());
-
-  if (!implementor.IsAllocated())
-    return {};
-
-  llvm::Expected<PythonObject> expected_py_return =
-      implementor.CallMethod("get_register_info");
-
-  if (!expected_py_return) {
-    llvm::consumeError(expected_py_return.takeError());
-    return {};
-  }
-
-  PythonObject py_return = std::move(expected_py_return.get());
-
-  if (py_return.get()) {
-    PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
-    return result_dict.CreateStructuredDictionary();
-  }
-  return StructuredData::DictionarySP();
-}
-
-StructuredData::ArraySP ScriptInterpreterPythonImpl::OSPlugin_ThreadsInfo(
-    StructuredData::ObjectSP os_plugin_object_sp) {
-  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-  if (!os_plugin_object_sp)
-    return {};
-
-  StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
-  if (!generic)
-    return {};
-
-  PythonObject implementor(PyRefType::Borrowed,
-                           (PyObject *)generic->GetValue());
-
-  if (!implementor.IsAllocated())
-    return {};
-
-  llvm::Expected<PythonObject> expected_py_return =
-      implementor.CallMethod("get_thread_info");
-
-  if (!expected_py_return) {
-    llvm::consumeError(expected_py_return.takeError());
-    return {};
-  }
-
-  PythonObject py_return = std::move(expected_py_return.get());
-
-  if (py_return.get()) {
-    PythonList result_list(PyRefType::Borrowed, py_return.get());
-    return result_list.CreateStructuredArray();
-  }
-  return StructuredData::ArraySP();
-}
-
-StructuredData::StringSP
-ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData(
-    StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
-  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-
-  if (!os_plugin_object_sp)
-    return {};
-
-  StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
-  if (!generic)
-    return {};
-  PythonObject implementor(PyRefType::Borrowed,
-                           (PyObject *)generic->GetValue());
-
-  if (!implementor.IsAllocated())
-    return {};
-
-  llvm::Expected<PythonObject> expected_py_return =
-      implementor.CallMethod("get_register_data", tid);
-
-  if (!expected_py_return) {
-    llvm::consumeError(expected_py_return.takeError());
-    return {};
-  }
-
-  PythonObject py_return = std::move(expected_py_return.get());
-
-  if (py_return.get()) {
-    PythonBytes result(PyRefType::Borrowed, py_return.get());
-    return result.CreateStructuredString();
-  }
-  return {};
-}
-
-StructuredData::DictionarySP ScriptInterpreterPythonImpl::OSPlugin_CreateThread(
-    StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid,
-    lldb::addr_t context) {
-  Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
-
-  if (!os_plugin_object_sp)
-    return {};
-
-  StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
-  if (!generic)
-    return {};
-
-  PythonObject implementor(PyRefType::Borrowed,
-                           (PyObject *)generic->GetValue());
-
-  if (!implementor.IsAllocated())
-    return {};
-
-  llvm::Expected<PythonObject> expected_py_return =
-      implementor.CallMethod("create_thread", tid, context);
-
-  if (!expected_py_return) {
-    llvm::consumeError(expected_py_return.takeError());
-    return {};
-  }
-
-  PythonObject py_return = std::move(expected_py_return.get());
-
-  if (py_return.get()) {
-    PythonDictionary result_dict(PyRefType::Borrowed, py_return.get());
-    return result_dict.CreateStructuredDictionary();
-  }
-  return StructuredData::DictionarySP();
-}
-
 StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
     const char *class_name, const StructuredDataImpl &args_data,
     std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) {
Index: lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.h
@@ -0,0 +1,44 @@
+//===-- OperatingSystemPythonInterface.h ------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_OPERATINGSYSTEMPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_OPERATINGSYSTEMPYTHONINTERFACE_H
+
+#include "lldb/Host/Config.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "ScriptedThreadPythonInterface.h"
+#include "lldb/Interpreter/Interfaces/OperatingSystemInterface.h"
+#include <optional>
+
+namespace lldb_private {
+class OperatingSystemPythonInterface
+    : virtual public OperatingSystemInterface,
+      virtual public ScriptedThreadPythonInterface {
+public:
+  OperatingSystemPythonInterface(ScriptInterpreterPythonImpl &interpreter);
+
+  StructuredData::GenericSP
+  CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx,
+                     StructuredData::DictionarySP args_sp,
+                     StructuredData::Generic *script_obj = nullptr) override;
+
+  StructuredData::DictionarySP CreateThread(lldb::tid_t tid,
+                                            lldb::addr_t context) override;
+
+  StructuredData::ArraySP GetThreadInfo() override;
+
+  StructuredData::DictionarySP GetRegisterInfo() override;
+
+  std::optional<std::string> GetRegisterContextForTID(lldb::tid_t tid) override;
+};
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_OPERATINGSYSTEMPYTHONINTERFACE_H
Index: lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/OperatingSystemPythonInterface.cpp
@@ -0,0 +1,77 @@
+//===-- ScriptedThreadPythonInterface.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/Utility/Log.h"
+#include "lldb/lldb-enumerations.h"
+
+#if LLDB_ENABLE_PYTHON
+
+// LLDB Python header must be included first
+#include "../lldb-python.h"
+
+#include "../SWIGPythonBridge.h"
+#include "../ScriptInterpreterPythonImpl.h"
+#include "OperatingSystemPythonInterface.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::python;
+using Locker = ScriptInterpreterPythonImpl::Locker;
+
+OperatingSystemPythonInterface::OperatingSystemPythonInterface(
+    ScriptInterpreterPythonImpl &interpreter)
+    : OperatingSystemInterface(), ScriptedThreadPythonInterface(interpreter) {}
+
+StructuredData::GenericSP OperatingSystemPythonInterface::CreatePluginObject(
+    llvm::StringRef class_name, ExecutionContext &exe_ctx,
+    StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
+  return ScriptedThreadPythonInterface::CreatePluginObject(class_name, exe_ctx,
+                                                           args_sp, script_obj);
+}
+
+StructuredData::DictionarySP
+OperatingSystemPythonInterface::CreateThread(lldb::tid_t tid,
+                                             lldb::addr_t context) {
+  Status error;
+  StructuredData::DictionarySP dict = Dispatch<StructuredData::DictionarySP>(
+      "create_thread", error, tid, context);
+
+  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
+    return {};
+
+  return dict;
+}
+
+StructuredData::ArraySP OperatingSystemPythonInterface::GetThreadInfo() {
+  Status error;
+  StructuredData::ArraySP arr =
+      Dispatch<StructuredData::ArraySP>("get_thread_info", error);
+
+  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
+    return {};
+
+  return arr;
+}
+
+StructuredData::DictionarySP OperatingSystemPythonInterface::GetRegisterInfo() {
+  return ScriptedThreadPythonInterface::GetRegisterInfo();
+}
+
+std::optional<std::string>
+OperatingSystemPythonInterface::GetRegisterContextForTID(lldb::tid_t tid) {
+  Status error;
+  StructuredData::ObjectSP obj = Dispatch("get_register_data", error, tid);
+
+  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+    return {};
+
+  return obj->GetAsString()->GetValue().str();
+}
+
+#endif
Index: lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
+++ lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt
@@ -20,6 +20,7 @@
 endif()
 
 add_lldb_library(lldbPluginScriptInterpreterPythonInterfaces
+  OperatingSystemPythonInterface.cpp
   ScriptedPythonInterface.cpp
   ScriptedProcessPythonInterface.cpp
   ScriptedThreadPythonInterface.cpp
Index: lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
===================================================================
--- lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
+++ lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
@@ -62,7 +62,7 @@
 
 protected:
   bool IsValid() const {
-    return m_python_object_sp && m_python_object_sp->IsValid();
+    return m_script_object_sp && m_script_object_sp->IsValid();
   }
 
   lldb::ThreadSP CreateThreadFromThreadInfo(
@@ -75,8 +75,9 @@
 
   lldb::ValueObjectSP m_thread_list_valobj_sp;
   std::unique_ptr<lldb_private::DynamicRegisterInfo> m_register_info_up;
-  lldb_private::ScriptInterpreter *m_interpreter;
-  lldb_private::StructuredData::ObjectSP m_python_object_sp;
+  lldb_private::ScriptInterpreter *m_interpreter = nullptr;
+  lldb::OperatingSystemInterfaceSP m_operating_system_interface_sp = nullptr;
+  lldb_private::StructuredData::GenericSP m_script_object_sp = nullptr;
 };
 
 #endif // LLDB_ENABLE_PYTHON
Index: lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
===================================================================
--- lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -74,47 +74,69 @@
 OperatingSystemPython::OperatingSystemPython(lldb_private::Process *process,
                                              const FileSpec &python_module_path)
     : OperatingSystem(process), m_thread_list_valobj_sp(), m_register_info_up(),
-      m_interpreter(nullptr), m_python_object_sp() {
+      m_interpreter(nullptr), m_script_object_sp() {
   if (!process)
     return;
   TargetSP target_sp = process->CalculateTarget();
   if (!target_sp)
     return;
   m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();
-  if (m_interpreter) {
-
-    std::string os_plugin_class_name(
-        python_module_path.GetFilename().AsCString(""));
-    if (!os_plugin_class_name.empty()) {
-      LoadScriptOptions options;
-      char python_module_path_cstr[PATH_MAX];
-      python_module_path.GetPath(python_module_path_cstr,
-                                 sizeof(python_module_path_cstr));
-      Status error;
-      if (m_interpreter->LoadScriptingModule(python_module_path_cstr, options,
-                                             error)) {
-        // Strip the ".py" extension if there is one
-        size_t py_extension_pos = os_plugin_class_name.rfind(".py");
-        if (py_extension_pos != std::string::npos)
-          os_plugin_class_name.erase(py_extension_pos);
-        // Add ".OperatingSystemPlugIn" to the module name to get a string like
-        // "modulename.OperatingSystemPlugIn"
-        os_plugin_class_name += ".OperatingSystemPlugIn";
-        StructuredData::ObjectSP object_sp =
-            m_interpreter->OSPlugin_CreatePluginObject(
-                os_plugin_class_name.c_str(), process->CalculateProcess());
-        if (object_sp && object_sp->IsValid())
-          m_python_object_sp = object_sp;
-      }
-    }
-  }
+  if (!m_interpreter)
+    return;
+
+  std::string os_plugin_class_name(
+      python_module_path.GetFilename().AsCString(""));
+  if (os_plugin_class_name.empty())
+    return;
+
+  LoadScriptOptions options;
+  char python_module_path_cstr[PATH_MAX];
+  python_module_path.GetPath(python_module_path_cstr,
+                             sizeof(python_module_path_cstr));
+  Status error;
+  if (!m_interpreter->LoadScriptingModule(python_module_path_cstr, options,
+                                          error))
+    return;
+
+  // Strip the ".py" extension if there is one
+  size_t py_extension_pos = os_plugin_class_name.rfind(".py");
+  if (py_extension_pos != std::string::npos)
+    os_plugin_class_name.erase(py_extension_pos);
+  // Add ".OperatingSystemPlugIn" to the module name to get a string like
+  // "modulename.OperatingSystemPlugIn"
+  os_plugin_class_name += ".OperatingSystemPlugIn";
+
+  auto operating_system_interface =
+      m_interpreter->CreateOperatingSystemInterface();
+  if (!operating_system_interface)
+    //    return llvm::createStringError(
+    //        llvm::inconvertibleErrorCode(),
+    //        "Failed to create scripted thread interface.");
+    return;
+
+  ExecutionContext exe_ctx(process);
+  StructuredData::GenericSP owned_script_object_sp =
+      operating_system_interface->CreatePluginObject(os_plugin_class_name,
+                                                     exe_ctx, nullptr);
+
+  if (!owned_script_object_sp)
+    //    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+    //                                   "Failed to create script object.");
+    return;
+  if (!owned_script_object_sp->IsValid())
+    //    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+    //                                   "Created script object is invalid.");
+    return;
+
+  m_script_object_sp = owned_script_object_sp;
+  m_operating_system_interface_sp = operating_system_interface;
 }
 
 OperatingSystemPython::~OperatingSystemPython() = default;
 
 DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
   if (m_register_info_up == nullptr) {
-    if (!m_interpreter || !m_python_object_sp)
+    if (!m_interpreter || !m_operating_system_interface_sp)
       return nullptr;
     Log *log = GetLog(LLDBLog::OS);
 
@@ -124,7 +146,7 @@
               m_process->GetID());
 
     StructuredData::DictionarySP dictionary =
-        m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp);
+        m_operating_system_interface_sp->GetRegisterInfo();
     if (!dictionary)
       return nullptr;
 
@@ -140,27 +162,11 @@
 bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
                                              ThreadList &core_thread_list,
                                              ThreadList &new_thread_list) {
-  if (!m_interpreter || !m_python_object_sp)
+  if (!m_interpreter || !m_operating_system_interface_sp)
     return false;
 
   Log *log = GetLog(LLDBLog::OS);
 
-  // First thing we have to do is to try to get the API lock, and the
-  // interpreter lock. We're going to change the thread content of the process,
-  // and we're going to use python, which requires the API lock to do it. We
-  // need the interpreter lock to make sure thread_info_dict stays alive.
-  //
-  // If someone already has the API lock, that is ok, we just want to avoid
-  // external code from making new API calls while this call is happening.
-  //
-  // This is a recursive lock so we can grant it to any Python code called on
-  // the stack below us.
-  Target &target = m_process->GetTarget();
-  std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
-                                                  std::defer_lock);
-  (void)api_lock.try_lock(); // See above.
-  auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
-
   LLDB_LOGF(log,
             "OperatingSystemPython::UpdateThreadList() fetching thread "
             "data from python for pid %" PRIu64,
@@ -170,7 +176,7 @@
   // the lldb_private::Process subclass, no memory threads will be in this
   // list.
   StructuredData::ArraySP threads_list =
-      m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp);
+      m_operating_system_interface_sp->GetThreadInfo();
 
   const uint32_t num_cores = core_thread_list.GetSize(false);
 
@@ -281,28 +287,12 @@
 OperatingSystemPython::CreateRegisterContextForThread(Thread *thread,
                                                       addr_t reg_data_addr) {
   RegisterContextSP reg_ctx_sp;
-  if (!m_interpreter || !m_python_object_sp || !thread)
+  if (!m_interpreter || !m_script_object_sp || !thread)
     return reg_ctx_sp;
 
   if (!IsOperatingSystemPluginThread(thread->shared_from_this()))
     return reg_ctx_sp;
 
-  // First thing we have to do is to try to get the API lock, and the
-  // interpreter lock. We're going to change the thread content of the process,
-  // and we're going to use python, which requires the API lock to do it. We
-  // need the interpreter lock to make sure thread_info_dict stays alive.
-  //
-  // If someone already has the API lock, that is ok, we just want to avoid
-  // external code from making new API calls while this call is happening.
-  //
-  // This is a recursive lock so we can grant it to any Python code called on
-  // the stack below us.
-  Target &target = m_process->GetTarget();
-  std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
-                                                  std::defer_lock);
-  (void)api_lock.try_lock(); // See above.
-  auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
-
   Log *log = GetLog(LLDBLog::Thread);
 
   if (reg_data_addr != LLDB_INVALID_ADDRESS) {
@@ -324,11 +314,11 @@
               ") fetching register data from python",
               thread->GetID(), thread->GetProtocolID());
 
-    StructuredData::StringSP reg_context_data =
-        m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp,
-                                                    thread->GetID());
+    std::optional<std::string> reg_context_data =
+        m_operating_system_interface_sp->GetRegisterContextForTID(
+            thread->GetID());
     if (reg_context_data) {
-      std::string value = std::string(reg_context_data->GetValue());
+      std::string value = *reg_context_data;
       DataBufferSP data_sp(new DataBufferHeap(value.c_str(), value.length()));
       if (data_sp->GetByteSize()) {
         RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory(
@@ -347,6 +337,7 @@
               "OperatingSystemPython::CreateRegisterContextForThread (tid "
               "= 0x%" PRIx64 ") forcing a dummy register context",
               thread->GetID());
+    Target &target = m_process->GetTarget();
     reg_ctx_sp = std::make_shared<RegisterContextDummy>(
         *thread, 0, target.GetArchitecture().GetAddressByteSize());
   }
@@ -372,26 +363,11 @@
             ", context = 0x%" PRIx64 ") fetching register data from python",
             tid, context);
 
-  if (m_interpreter && m_python_object_sp) {
-    // First thing we have to do is to try to get the API lock, and the
-    // interpreter lock. We're going to change the thread content of the
-    // process, and we're going to use python, which requires the API lock to
-    // do it. We need the interpreter lock to make sure thread_info_dict stays
-    // alive.
-    //
-    // If someone already has the API lock, that is ok, we just want to avoid
-    // external code from making new API calls while this call is happening.
-    //
-    // This is a recursive lock so we can grant it to any Python code called on
-    // the stack below us.
-    Target &target = m_process->GetTarget();
-    std::unique_lock<std::recursive_mutex> api_lock(target.GetAPIMutex(),
-                                                    std::defer_lock);
-    (void)api_lock.try_lock(); // See above.
-    auto interpreter_lock = m_interpreter->AcquireInterpreterLock();
+  if (m_interpreter && m_script_object_sp) {
 
     StructuredData::DictionarySP thread_info_dict =
-        m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context);
+        m_operating_system_interface_sp->CreateThread(tid, context);
+
     std::vector<bool> core_used_map;
     if (thread_info_dict) {
       ThreadList core_threads(m_process);
Index: lldb/include/lldb/lldb-forward.h
===================================================================
--- lldb/include/lldb/lldb-forward.h
+++ lldb/include/lldb/lldb-forward.h
@@ -130,6 +130,7 @@
 class ObjectFile;
 class ObjectFileJITDelegate;
 class OperatingSystem;
+class OperatingSystemInterface;
 class OptionGroup;
 class OptionGroupOptions;
 class OptionGroupPlatform;
@@ -359,6 +360,8 @@
 typedef std::weak_ptr<lldb_private::ObjectFileJITDelegate>
     ObjectFileJITDelegateWP;
 typedef std::unique_ptr<lldb_private::OperatingSystem> OperatingSystemUP;
+typedef std::shared_ptr<lldb_private::OperatingSystemInterface>
+    OperatingSystemInterfaceSP;
 typedef std::shared_ptr<lldb_private::OptionValue> OptionValueSP;
 typedef std::weak_ptr<lldb_private::OptionValue> OptionValueWP;
 typedef std::shared_ptr<lldb_private::OptionValueProperties>
Index: lldb/include/lldb/Interpreter/ScriptInterpreter.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -21,6 +21,7 @@
 #include "lldb/Core/ThreadedCommunication.h"
 #include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/StreamFile.h"
+#include "lldb/Interpreter/Interfaces/OperatingSystemInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h"
 #include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
@@ -252,12 +253,6 @@
     return lldb::ValueObjectListSP();
   }
 
-  virtual StructuredData::GenericSP
-  OSPlugin_CreatePluginObject(const char *class_name,
-                              lldb::ProcessSP process_sp) {
-    return StructuredData::GenericSP();
-  }
-
   virtual StructuredData::DictionarySP
   OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) {
     return StructuredData::DictionarySP();
@@ -593,6 +588,10 @@
     return std::make_shared<ScriptedThreadInterface>();
   }
 
+  virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() {
+    return std::make_shared<OperatingSystemInterface>();
+  }
+
   ScriptedPlatformInterface &GetScriptedPlatformInterface() {
     return *m_scripted_platform_interface_up;
   }
Index: lldb/include/lldb/Interpreter/Interfaces/OperatingSystemInterface.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Interpreter/Interfaces/OperatingSystemInterface.h
@@ -0,0 +1,33 @@
+//===-- OperatingSystemInterface.h ------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_INTERPRETER_INTERFACES_OPERATINGSYSTEMINTERFACE_H
+#define LLDB_INTERPRETER_INTERFACES_OPERATINGSYSTEMINTERFACE_H
+
+#include "ScriptedThreadInterface.h"
+#include "lldb/Core/StructuredDataImpl.h"
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+class OperatingSystemInterface : virtual public ScriptedThreadInterface {
+public:
+  virtual StructuredData::DictionarySP CreateThread(lldb::tid_t tid,
+                                                    lldb::addr_t context) {
+    return {};
+  }
+
+  virtual StructuredData::ArraySP GetThreadInfo() { return {}; }
+
+  virtual std::optional<std::string> GetRegisterContextForTID(lldb::tid_t tid) {
+    return std::nullopt;
+  }
+};
+} // namespace lldb_private
+
+#endif // LLDB_INTERPRETER_INTERFACES_OPERATINGSYSTEMINTERFACE_H
Index: lldb/bindings/python/python.swig
===================================================================
--- lldb/bindings/python/python.swig
+++ lldb/bindings/python/python.swig
@@ -116,6 +116,7 @@
 %{
 #include "../source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
 #include "../source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h"
+#include "../include/lldb/Target/ExecutionContext.h"
 #include "../bindings/python/python-swigsafecast.swig"
 using namespace lldb_private;
 using namespace lldb_private::python;
Index: lldb/bindings/python/python-wrapper.swig
===================================================================
--- lldb/bindings/python/python-wrapper.swig
+++ lldb/bindings/python/python-wrapper.swig
@@ -263,11 +263,20 @@
   }
 
   PythonObject result = {};
-  if (arg_info.get().max_positional_args == 2) {
+  switch (arg_info.get().max_positional_args) {
+    case 1:
+      // FIXME: Since this is used by different scripting affordances, they can have different number
+      // of argument but also different types of arguments (i.e SBExecutionContect vs SBProcess)
+      // We need to have a more reliable way to forward positional arguments.
+      result = pfunc(SWIGBridge::ToSWIGWrapper(exe_ctx_sp->GetProcessSP()));
+      break;
+    case 2:
       result = pfunc(SWIGBridge::ToSWIGWrapper(exe_ctx_sp), SWIGBridge::ToSWIGWrapper(args_impl));
-  } else {
-    error_string.assign("wrong number of arguments in __init__, should be 2 "
-                        "(not including self)");
+      break;
+    default:
+      error_string.assign("wrong number of arguments in __init__, should be 2 "
+                          "(not including self)");
+      break;
   }
   return result;
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH]... Med Ismail Bennani via Phabricator via lldb-commits

Reply via email to