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

This patch should improve error reporting by passing the status object from the 
Scripted Process plugin down to the python interface, by converting it to a 
SBError (wrapped into a PyObject).

This way, the Scripted Process python implementation can report back errors 
when reading or writing memory to lldb.

This will also be used when initializing the ScriptedProcess python object.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134033

Files:
  lldb/bindings/python/python-swigsafecast.swig
  lldb/examples/python/scripted_process/scripted_process.py
  lldb/include/lldb/API/SBError.h
  lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
  lldb/include/lldb/lldb-forward.h
  lldb/source/API/SBError.cpp
  lldb/source/Interpreter/ScriptInterpreter.cpp
  lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
  lldb/source/Plugins/Process/scripted/ScriptedProcess.h
  lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
  
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
  
lldb/test/API/functionalities/scripted_process_passthru/scripted_process_passthru.py
  lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
===================================================================
--- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -193,6 +193,52 @@
   return python::PythonObject();
 }
 
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::ValueObjectSP value_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::TargetSP target_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::ProcessSP process_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::StatusSP status_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(const StructuredDataImpl &data_impl) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::ThreadSP thread_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::StackFrameSP frame_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::DebuggerSP debugger_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(const TypeSummaryOptions &summary_options) {
+  return python::PythonObject();
+}
+python::PythonObject lldb_private::ToSWIGWrapper(const SymbolContext &sym_ctx) {
+  return python::PythonObject();
+}
+
 python::PythonObject lldb_private::LLDBSwigPythonCreateScriptedProcess(
     const char *python_class_name, const char *session_dictionary_name,
     const lldb::TargetSP &target_sp, const StructuredDataImpl &args_impl,
Index: lldb/test/API/functionalities/scripted_process_passthru/scripted_process_passthru.py
===================================================================
--- lldb/test/API/functionalities/scripted_process_passthru/scripted_process_passthru.py
+++ lldb/test/API/functionalities/scripted_process_passthru/scripted_process_passthru.py
@@ -46,11 +46,20 @@
 
         return data
 
+    def write_memory_at_address(self, addr: int, buf : bytes, size: int) -> lldb.SBData:
+        error = lldb.SBError()
+        bytes_written = self.parent_process.WriteMemory(addr, size, error)
+
+        if error.Fail():
+            return 0
+
+        return bytes_written
+
     def get_loaded_images(self):
         return self.loaded_images
 
     def get_process_id(self) -> int:
-        return 42
+        return self.parent_process.GetProcessID()
 
     def should_stop(self) -> bool:
         return True
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -56,6 +56,9 @@
 
   lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size,
                                             Status &error) override;
+                                         
+  size_t WriteMemoryAtAddress(lldb::addr_t address, const void* buf,
+                              size_t size, Status &error) override;
 
   StructuredData::ArraySP GetLoadedImages() override;
 
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -155,8 +155,52 @@
 
 lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
     lldb::addr_t address, size_t size, Status &error) {
-  return Dispatch<lldb::DataExtractorSP>("read_memory_at_address", error,
-                                         address, size);
+  
+  // Turn the `Status` arguement into an `SBError` to pass it down to the Python call.
+  StatusSP status_sp = std::make_shared<Status>(error);
+  PythonObject* sb_error = new PythonObject(ToSWIGWrapper(status_sp));
+  
+  Status caller_status;
+  DataExtractorSP data_sp = Dispatch<lldb::DataExtractorSP>("read_memory_at_address", caller_status,
+                                         address, size, sb_error);
+  // Convert the `SBError` back to a `Status` object and assign it to the original `error` reference.
+  Status sb_extractor_status;
+  error = ExtractValueFromPythonObject<Status>(*sb_error, sb_extractor_status);
+
+//  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+//    return ScriptedInterface::ErrorWithMessage<size_t>(
+//        LLVM_PRETTY_FUNCTION,
+//        llvm::Twine("Null or invalid object (" +
+//                    llvm::Twine(error.AsCString()) + llvm::Twine(")."))
+//            .str(),
+//        error);
+  
+  return data_sp;
+}
+
+size_t ScriptedProcessPythonInterface::WriteMemoryAtAddress(
+    lldb::addr_t address, const void* buf, size_t size, Status &error) {
+  
+  // Turn the `Status` arguement into an `SBError` to pass it down to the Python call.
+  StatusSP status_sp = std::make_shared<Status>(error);
+  PythonObject* sb_error = new PythonObject(ToSWIGWrapper(status_sp));
+  
+  Status caller_status;
+  StructuredData::ObjectSP obj = Dispatch("write_memory_at_address", caller_status, address, buf, size, sb_error);
+
+  // Convert the `SBError` back to a `Status` object and assign it to the original `error` reference.
+  Status sb_extractor_status;
+  error = ExtractValueFromPythonObject<Status>(*sb_error, sb_extractor_status);
+  
+  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error))
+    return ScriptedInterface::ErrorWithMessage<size_t>(
+        LLVM_PRETTY_FUNCTION,
+        llvm::Twine("Null or invalid object (" +
+                    llvm::Twine(error.AsCString()) + llvm::Twine(")."))
+            .str(),
+        error);
+
+  return obj->GetIntegerValue();
 }
 
 StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
Index: lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -23,7 +23,66 @@
 #include "lldb/lldb-types.h"
 #include "llvm/Support/Error.h"
 
+namespace lldb {
+class SBEvent;
+class SBCommandReturnObject;
+class SBValue;
+class SBStream;
+class SBStructuredData;
+}
+
 namespace lldb_private {
+  namespace python {
+  typedef struct swig_type_info swig_type_info;
+  
+  python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info);
+
+  /// A class that automatically clears an SB object when it goes out of scope.
+  /// Use for cases where the SB object points to a temporary/unowned entity.
+  template <typename T> class ScopedPythonObject : PythonObject {
+  public:
+    ScopedPythonObject(T *sb, swig_type_info *info)
+        : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {}
+    ~ScopedPythonObject() {
+      if (m_sb)
+        *m_sb = T();
+    }
+    ScopedPythonObject(ScopedPythonObject &&rhs)
+        : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {}
+    ScopedPythonObject(const ScopedPythonObject &) = delete;
+    ScopedPythonObject &operator=(const ScopedPythonObject &) = delete;
+    ScopedPythonObject &operator=(ScopedPythonObject &&) = delete;
+
+    const PythonObject &obj() const { return *this; }
+
+  private:
+    T *m_sb;
+  };
+
+  python::PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp);
+  python::PythonObject ToSWIGWrapper(lldb::TargetSP target_sp);
+  python::PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp);
+  python::PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp);
+  python::PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp);
+  python::PythonObject ToSWIGWrapper(lldb::StatusSP status_sp);
+  python::PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl);
+  python::PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp);
+  python::PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp);
+  python::PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp);
+  python::PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp);
+  python::PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp);
+  python::PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp);
+  python::PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options);
+  python::PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx);
+
+  python::PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb);
+  python::PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb);
+  python::PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
+
+  python::ScopedPythonObject<lldb::SBCommandReturnObject> ToSWIGWrapper(CommandReturnObject &cmd_retobj);
+  python::ScopedPythonObject<lldb::SBEvent> ToSWIGWrapper(Event *event);
+  
+  }
 
 // GetPythonValueFormatString provides a system independent type safe way to
 // convert a variable's type into a python value format. Python value formats
@@ -32,6 +91,8 @@
 // change.
 
 template <typename T> const char *GetPythonValueFormatString(T t);
+template <> const char *GetPythonValueFormatString(python::PythonObject*);
+template <> const char *GetPythonValueFormatString(const void *);
 template <> const char *GetPythonValueFormatString(char *);
 template <> const char *GetPythonValueFormatString(char);
 template <> const char *GetPythonValueFormatString(unsigned char);
Index: lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp
@@ -14,13 +14,19 @@
 // LLDB Python header must be included first
 #include "lldb-python.h"
 
+#include "PythonDataObjects.h"
 #include "SWIGPythonBridge.h"
 
+// DOC: https://docs.python.org/3/c-api/arg.html#building-values
+
 using namespace lldb;
 
 namespace lldb_private {
 
 template <typename T> const char *GetPythonValueFormatString(T t);
+// FIXME: This should probably be a PyObject * instead of PythonObject
+template <> const char *GetPythonValueFormatString(python::PythonObject*) { return "O"; }
+template <> const char *GetPythonValueFormatString(const void *) { return "y"; }
 template <> const char *GetPythonValueFormatString(char *) { return "s"; }
 template <> const char *GetPythonValueFormatString(char) { return "b"; }
 template <> const char *GetPythonValueFormatString(unsigned char) {
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.h
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -83,6 +83,9 @@
 
   size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
                       Status &error) override;
+  
+  size_t DoWriteMemory(lldb::addr_t addr, const void *buf,
+                       size_t size, Status &error) override;
 
   ArchSpec GetArchitecture();
 
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -338,6 +338,21 @@
   return size;
 }
 
+size_t ScriptedProcess::DoWriteMemory(lldb::addr_t addr, const void *buf,
+                             size_t size, Status &error) {
+  if (!m_interpreter)
+    return ScriptedInterface::ErrorWithMessage<size_t>(
+        LLVM_PRETTY_FUNCTION, "No interpreter.", error);
+
+  size_t bytes_written = GetInterface().WriteMemoryAtAddress(addr, buf, size, error);
+
+  if (!bytes_written || error.Fail())
+    return ScriptedInterface::ErrorWithMessage<size_t>(
+        LLVM_PRETTY_FUNCTION, "Failed to write buffer to memory.", error);
+
+  return size;
+}
+
 ArchSpec ScriptedProcess::GetArchitecture() {
   return GetTarget().GetArchitecture();
 }
Index: lldb/source/Interpreter/ScriptInterpreter.cpp
===================================================================
--- lldb/source/Interpreter/ScriptInterpreter.cpp
+++ lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -81,8 +81,8 @@
 
 Status
 ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const {
-  if (error.m_opaque_up)
-    return *error.m_opaque_up.get();
+  if (error.m_opaque_sp)
+    return *error.m_opaque_sp;
 
   return Status();
 }
Index: lldb/source/API/SBError.cpp
===================================================================
--- lldb/source/API/SBError.cpp
+++ lldb/source/API/SBError.cpp
@@ -22,7 +22,11 @@
 SBError::SBError(const SBError &rhs) {
   LLDB_INSTRUMENT_VA(this, rhs);
 
-  m_opaque_up = clone(rhs.m_opaque_up);
+  m_opaque_sp = clone(rhs.m_opaque_sp);
+}
+
+SBError::SBError(const lldb::StatusSP &status_sp) : m_opaque_sp(status_sp) {
+  LLDB_INSTRUMENT_VA(this, status_sp);
 }
 
 SBError::~SBError() = default;
@@ -31,31 +35,31 @@
   LLDB_INSTRUMENT_VA(this, rhs);
 
   if (this != &rhs)
-    m_opaque_up = clone(rhs.m_opaque_up);
+    m_opaque_sp = clone(rhs.m_opaque_sp);
   return *this;
 }
 
 const char *SBError::GetCString() const {
   LLDB_INSTRUMENT_VA(this);
 
-  if (m_opaque_up)
-    return m_opaque_up->AsCString();
+  if (m_opaque_sp)
+    return m_opaque_sp->AsCString();
   return nullptr;
 }
 
 void SBError::Clear() {
   LLDB_INSTRUMENT_VA(this);
 
-  if (m_opaque_up)
-    m_opaque_up->Clear();
+  if (m_opaque_sp)
+    m_opaque_sp->Clear();
 }
 
 bool SBError::Fail() const {
   LLDB_INSTRUMENT_VA(this);
 
   bool ret_value = false;
-  if (m_opaque_up)
-    ret_value = m_opaque_up->Fail();
+  if (m_opaque_sp)
+    ret_value = m_opaque_sp->Fail();
 
 
   return ret_value;
@@ -65,8 +69,8 @@
   LLDB_INSTRUMENT_VA(this);
 
   bool ret_value = true;
-  if (m_opaque_up)
-    ret_value = m_opaque_up->Success();
+  if (m_opaque_sp)
+    ret_value = m_opaque_sp->Success();
 
   return ret_value;
 }
@@ -75,8 +79,8 @@
   LLDB_INSTRUMENT_VA(this);
 
   uint32_t err = 0;
-  if (m_opaque_up)
-    err = m_opaque_up->GetError();
+  if (m_opaque_sp)
+    err = m_opaque_sp->GetError();
 
 
   return err;
@@ -86,8 +90,8 @@
   LLDB_INSTRUMENT_VA(this);
 
   ErrorType err_type = eErrorTypeInvalid;
-  if (m_opaque_up)
-    err_type = m_opaque_up->GetType();
+  if (m_opaque_sp)
+    err_type = m_opaque_sp->GetType();
 
   return err_type;
 }
@@ -96,40 +100,40 @@
   LLDB_INSTRUMENT_VA(this, err, type);
 
   CreateIfNeeded();
-  m_opaque_up->SetError(err, type);
+  m_opaque_sp->SetError(err, type);
 }
 
 void SBError::SetError(const Status &lldb_error) {
   CreateIfNeeded();
-  *m_opaque_up = lldb_error;
+  *m_opaque_sp = lldb_error;
 }
 
 void SBError::SetErrorToErrno() {
   LLDB_INSTRUMENT_VA(this);
 
   CreateIfNeeded();
-  m_opaque_up->SetErrorToErrno();
+  m_opaque_sp->SetErrorToErrno();
 }
 
 void SBError::SetErrorToGenericError() {
   LLDB_INSTRUMENT_VA(this);
 
   CreateIfNeeded();
-  m_opaque_up->SetErrorToGenericError();
+  m_opaque_sp->SetErrorToGenericError();
 }
 
 void SBError::SetErrorString(const char *err_str) {
   LLDB_INSTRUMENT_VA(this, err_str);
 
   CreateIfNeeded();
-  m_opaque_up->SetErrorString(err_str);
+  m_opaque_sp->SetErrorString(err_str);
 }
 
 int SBError::SetErrorStringWithFormat(const char *format, ...) {
   CreateIfNeeded();
   va_list args;
   va_start(args, format);
-  int num_chars = m_opaque_up->SetErrorStringWithVarArg(format, args);
+  int num_chars = m_opaque_sp->SetErrorStringWithVarArg(format, args);
   va_end(args);
   return num_chars;
 }
@@ -141,33 +145,33 @@
 SBError::operator bool() const {
   LLDB_INSTRUMENT_VA(this);
 
-  return m_opaque_up != nullptr;
+  return m_opaque_sp != nullptr;
 }
 
 void SBError::CreateIfNeeded() {
-  if (m_opaque_up == nullptr)
-    m_opaque_up = std::make_unique<Status>();
+  if (m_opaque_sp == nullptr)
+    m_opaque_sp = std::make_unique<Status>();
 }
 
-lldb_private::Status *SBError::operator->() { return m_opaque_up.get(); }
+lldb_private::Status *SBError::operator->() { return m_opaque_sp.get(); }
 
-lldb_private::Status *SBError::get() { return m_opaque_up.get(); }
+lldb_private::Status *SBError::get() { return m_opaque_sp.get(); }
 
 lldb_private::Status &SBError::ref() {
   CreateIfNeeded();
-  return *m_opaque_up;
+  return *m_opaque_sp;
 }
 
 const lldb_private::Status &SBError::operator*() const {
   // Be sure to call "IsValid()" before calling this function or it will crash
-  return *m_opaque_up;
+  return *m_opaque_sp;
 }
 
 bool SBError::GetDescription(SBStream &description) {
   LLDB_INSTRUMENT_VA(this, description);
 
-  if (m_opaque_up) {
-    if (m_opaque_up->Success())
+  if (m_opaque_sp) {
+    if (m_opaque_sp->Success())
       description.Printf("success");
     else {
       const char *err_string = GetCString();
Index: lldb/include/lldb/lldb-forward.h
===================================================================
--- lldb/include/lldb/lldb-forward.h
+++ lldb/include/lldb/lldb-forward.h
@@ -393,6 +393,7 @@
     StackFrameRecognizerSP;
 typedef std::unique_ptr<lldb_private::StackFrameRecognizerManager>
     StackFrameRecognizerManagerUP;
+typedef std::shared_ptr<lldb_private::Status> StatusSP;
 typedef std::shared_ptr<lldb_private::StopInfo> StopInfoSP;
 typedef std::shared_ptr<lldb_private::Stream> StreamSP;
 typedef std::shared_ptr<lldb_private::StreamFile> StreamFileSP;
Index: lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
+++ lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
@@ -69,6 +69,11 @@
   ReadMemoryAtAddress(lldb::addr_t address, size_t size, Status &error) {
     return nullptr;
   }
+  
+  virtual size_t
+  WriteMemoryAtAddress(lldb::addr_t address, const void* buf, size_t size, Status &error) {
+    return 0;
+  }
 
   virtual StructuredData::ArraySP GetLoadedImages() { return nullptr; }
 
Index: lldb/include/lldb/API/SBError.h
===================================================================
--- lldb/include/lldb/API/SBError.h
+++ lldb/include/lldb/API/SBError.h
@@ -22,6 +22,8 @@
   SBError();
 
   SBError(const lldb::SBError &rhs);
+  
+  SBError(const lldb::StatusSP &status_sp);
 
   ~SBError();
 
@@ -90,7 +92,7 @@
   void SetError(const lldb_private::Status &lldb_error);
 
 private:
-  std::unique_ptr<lldb_private::Status> m_opaque_up;
+  std::shared_ptr<lldb_private::Status> m_opaque_sp;
 
   void CreateIfNeeded();
 };
Index: lldb/examples/python/scripted_process/scripted_process.py
===================================================================
--- lldb/examples/python/scripted_process/scripted_process.py
+++ lldb/examples/python/scripted_process/scripted_process.py
@@ -167,6 +167,19 @@
         """
         pass
 
+    def write_memory_at_address(self, addr, buf, size):
+        """ Write a buffer at a certain address in the scripted process memory.
+
+        Args:
+            addr (int): Address from which we should start reading.
+            buf  (bytes): The buffer storing the data to be written.
+            size (int): Size of the data to be written.
+
+        Returns:
+            int: Size of the data written.
+        """
+        return 0
+
     def get_loaded_images(self):
         """ Get the list of loaded images for the scripted process.
 
Index: lldb/bindings/python/python-swigsafecast.swig
===================================================================
--- lldb/bindings/python/python-swigsafecast.swig
+++ lldb/bindings/python/python-swigsafecast.swig
@@ -5,28 +5,6 @@
   return {PyRefType::Owned, SWIG_NewPointerObj(obj, info, SWIG_POINTER_OWN)};
 }
 
-/// A class that automatically clears an SB object when it goes out of scope.
-/// Use for cases where the SB object points to a temporary/unowned entity.
-template <typename T> class ScopedPythonObject : PythonObject {
-public:
-  ScopedPythonObject(T *sb, swig_type_info *info)
-      : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {}
-  ~ScopedPythonObject() {
-    if (m_sb)
-      *m_sb = T();
-  }
-  ScopedPythonObject(ScopedPythonObject &&rhs)
-      : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {}
-  ScopedPythonObject(const ScopedPythonObject &) = delete;
-  ScopedPythonObject &operator=(const ScopedPythonObject &) = delete;
-  ScopedPythonObject &operator=(ScopedPythonObject &&) = delete;
-
-  const PythonObject &obj() const { return *this; }
-
-private:
-  T *m_sb;
-};
-
 PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb) {
   return ToSWIGHelper(value_sb.release(), SWIGTYPE_p_lldb__SBValue);
 }
@@ -55,6 +33,11 @@
                       SWIGTYPE_p_lldb__SBBreakpoint);
 }
 
+PythonObject ToSWIGWrapper(lldb::StatusSP status_sp) {
+  return ToSWIGHelper(new lldb::SBError(std::move(status_sp)),
+                                            SWIGTYPE_p_lldb__SBError);
+}
+
 PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb) {
   return ToSWIGHelper(stream_sb.release(), SWIGTYPE_p_lldb__SBStream);
 }
_______________________________________________
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