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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits