[lldb] Fix [some] leaks in python bindings
Using an lldb_private object in the bindings involves three steps
- wrapping the object in it's lldb::SB variant
- using swig to convert/wrap that to a PyObject
- wrapping *that* in a lldb_private::python::PythonObject
Our SBTypeToSWIGWrapper was only handling the middle part. This doesn't
just result in increased boilerplate in the callers, but is also a
functionality problem, as it's very hard to get the lifetime of of all
of these objects right. Most of the callers are creating the SB object
(step 1) on the stack, which means that we end up with dangling python
objects after the function terminates. Most of the time this isn't a
problem, because the python code does not need to persist the objects.
However, there are legitimate cases where they can do it (and even if
the use case is not completely legitimate, crashing is not the best
response to that).
For this reason, some of our code creates the SB object on the heap, but
it has another problem -- it never gets cleaned up.
This patch begins to add a new function (ToSWIGWrapper), which does all
of the three steps, while properly taking care of ownership. In the
first step, I have converted most of the leaky code (except for
SBStructuredData, which needs a bit more work).
Differential Revision: https://reviews.llvm.org/D114259
2021-11-18 21:27:27 +01:00
|
|
|
namespace lldb_private {
|
|
|
|
|
namespace python {
|
|
|
|
|
|
|
|
|
|
PythonObject ToSWIGHelper(void *obj, swig_type_info *info) {
|
|
|
|
|
return {PyRefType::Owned, SWIG_NewPointerObj(obj, info, SWIG_POINTER_OWN)};
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb) {
|
[lldb] Fix [some] leaks in python bindings
Using an lldb_private object in the bindings involves three steps
- wrapping the object in it's lldb::SB variant
- using swig to convert/wrap that to a PyObject
- wrapping *that* in a lldb_private::python::PythonObject
Our SBTypeToSWIGWrapper was only handling the middle part. This doesn't
just result in increased boilerplate in the callers, but is also a
functionality problem, as it's very hard to get the lifetime of of all
of these objects right. Most of the callers are creating the SB object
(step 1) on the stack, which means that we end up with dangling python
objects after the function terminates. Most of the time this isn't a
problem, because the python code does not need to persist the objects.
However, there are legitimate cases where they can do it (and even if
the use case is not completely legitimate, crashing is not the best
response to that).
For this reason, some of our code creates the SB object on the heap, but
it has another problem -- it never gets cleaned up.
This patch begins to add a new function (ToSWIGWrapper), which does all
of the three steps, while properly taking care of ownership. In the
first step, I have converted most of the leaky code (except for
SBStructuredData, which needs a bit more work).
Differential Revision: https://reviews.llvm.org/D114259
2021-11-18 21:27:27 +01:00
|
|
|
return ToSWIGHelper(value_sb.release(), SWIGTYPE_p_lldb__SBValue);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::ValueObjectSP value_sp) {
|
|
|
|
|
return ToSWIGWrapper(std::unique_ptr<lldb::SBValue>(new lldb::SBValue(value_sp)));
|
[lldb] Fix [some] leaks in python bindings
Using an lldb_private object in the bindings involves three steps
- wrapping the object in it's lldb::SB variant
- using swig to convert/wrap that to a PyObject
- wrapping *that* in a lldb_private::python::PythonObject
Our SBTypeToSWIGWrapper was only handling the middle part. This doesn't
just result in increased boilerplate in the callers, but is also a
functionality problem, as it's very hard to get the lifetime of of all
of these objects right. Most of the callers are creating the SB object
(step 1) on the stack, which means that we end up with dangling python
objects after the function terminates. Most of the time this isn't a
problem, because the python code does not need to persist the objects.
However, there are legitimate cases where they can do it (and even if
the use case is not completely legitimate, crashing is not the best
response to that).
For this reason, some of our code creates the SB object on the heap, but
it has another problem -- it never gets cleaned up.
This patch begins to add a new function (ToSWIGWrapper), which does all
of the three steps, while properly taking care of ownership. In the
first step, I have converted most of the leaky code (except for
SBStructuredData, which needs a bit more work).
Differential Revision: https://reviews.llvm.org/D114259
2021-11-18 21:27:27 +01:00
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::TargetSP target_sp) {
|
[lldb] Fix [some] leaks in python bindings
Using an lldb_private object in the bindings involves three steps
- wrapping the object in it's lldb::SB variant
- using swig to convert/wrap that to a PyObject
- wrapping *that* in a lldb_private::python::PythonObject
Our SBTypeToSWIGWrapper was only handling the middle part. This doesn't
just result in increased boilerplate in the callers, but is also a
functionality problem, as it's very hard to get the lifetime of of all
of these objects right. Most of the callers are creating the SB object
(step 1) on the stack, which means that we end up with dangling python
objects after the function terminates. Most of the time this isn't a
problem, because the python code does not need to persist the objects.
However, there are legitimate cases where they can do it (and even if
the use case is not completely legitimate, crashing is not the best
response to that).
For this reason, some of our code creates the SB object on the heap, but
it has another problem -- it never gets cleaned up.
This patch begins to add a new function (ToSWIGWrapper), which does all
of the three steps, while properly taking care of ownership. In the
first step, I have converted most of the leaky code (except for
SBStructuredData, which needs a bit more work).
Differential Revision: https://reviews.llvm.org/D114259
2021-11-18 21:27:27 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBTarget(std::move(target_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBTarget);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::ProcessSP process_sp) {
|
[lldb] Fix [some] leaks in python bindings
Using an lldb_private object in the bindings involves three steps
- wrapping the object in it's lldb::SB variant
- using swig to convert/wrap that to a PyObject
- wrapping *that* in a lldb_private::python::PythonObject
Our SBTypeToSWIGWrapper was only handling the middle part. This doesn't
just result in increased boilerplate in the callers, but is also a
functionality problem, as it's very hard to get the lifetime of of all
of these objects right. Most of the callers are creating the SB object
(step 1) on the stack, which means that we end up with dangling python
objects after the function terminates. Most of the time this isn't a
problem, because the python code does not need to persist the objects.
However, there are legitimate cases where they can do it (and even if
the use case is not completely legitimate, crashing is not the best
response to that).
For this reason, some of our code creates the SB object on the heap, but
it has another problem -- it never gets cleaned up.
This patch begins to add a new function (ToSWIGWrapper), which does all
of the three steps, while properly taking care of ownership. In the
first step, I have converted most of the leaky code (except for
SBStructuredData, which needs a bit more work).
Differential Revision: https://reviews.llvm.org/D114259
2021-11-18 21:27:27 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBProcess(std::move(process_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBProcess);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp) {
|
[lldb] Fix [some] leaks in python bindings
Using an lldb_private object in the bindings involves three steps
- wrapping the object in it's lldb::SB variant
- using swig to convert/wrap that to a PyObject
- wrapping *that* in a lldb_private::python::PythonObject
Our SBTypeToSWIGWrapper was only handling the middle part. This doesn't
just result in increased boilerplate in the callers, but is also a
functionality problem, as it's very hard to get the lifetime of of all
of these objects right. Most of the callers are creating the SB object
(step 1) on the stack, which means that we end up with dangling python
objects after the function terminates. Most of the time this isn't a
problem, because the python code does not need to persist the objects.
However, there are legitimate cases where they can do it (and even if
the use case is not completely legitimate, crashing is not the best
response to that).
For this reason, some of our code creates the SB object on the heap, but
it has another problem -- it never gets cleaned up.
This patch begins to add a new function (ToSWIGWrapper), which does all
of the three steps, while properly taking care of ownership. In the
first step, I have converted most of the leaky code (except for
SBStructuredData, which needs a bit more work).
Differential Revision: https://reviews.llvm.org/D114259
2021-11-18 21:27:27 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBThreadPlan(std::move(thread_plan_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBThreadPlan);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp) {
|
[lldb] Fix [some] leaks in python bindings
Using an lldb_private object in the bindings involves three steps
- wrapping the object in it's lldb::SB variant
- using swig to convert/wrap that to a PyObject
- wrapping *that* in a lldb_private::python::PythonObject
Our SBTypeToSWIGWrapper was only handling the middle part. This doesn't
just result in increased boilerplate in the callers, but is also a
functionality problem, as it's very hard to get the lifetime of of all
of these objects right. Most of the callers are creating the SB object
(step 1) on the stack, which means that we end up with dangling python
objects after the function terminates. Most of the time this isn't a
problem, because the python code does not need to persist the objects.
However, there are legitimate cases where they can do it (and even if
the use case is not completely legitimate, crashing is not the best
response to that).
For this reason, some of our code creates the SB object on the heap, but
it has another problem -- it never gets cleaned up.
This patch begins to add a new function (ToSWIGWrapper), which does all
of the three steps, while properly taking care of ownership. In the
first step, I have converted most of the leaky code (except for
SBStructuredData, which needs a bit more work).
Differential Revision: https://reviews.llvm.org/D114259
2021-11-18 21:27:27 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBBreakpoint(std::move(breakpoint_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBBreakpoint);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(const Status& status) {
|
2022-11-18 13:53:57 -08:00
|
|
|
return ToSWIGHelper(new lldb::SBError(status), SWIGTYPE_p_lldb__SBError);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-29 10:43:33 -08:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb) {
|
|
|
|
|
return ToSWIGHelper(stream_sb.release(), SWIGTYPE_p_lldb__SBStream);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb) {
|
2021-11-26 09:46:31 +01:00
|
|
|
return ToSWIGHelper(data_sb.release(), SWIGTYPE_p_lldb__SBStructuredData);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(const StructuredDataImpl &data_impl) {
|
|
|
|
|
return ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData>(new lldb::SBStructuredData(data_impl)));
|
2021-11-26 09:46:31 +01:00
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::ThreadSP thread_sp) {
|
2021-11-18 08:11:34 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBThread(std::move(thread_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBThread);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::StackFrameSP frame_sp) {
|
2021-11-18 08:11:34 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBFrame(std::move(frame_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBFrame);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::DebuggerSP debugger_sp) {
|
2021-11-18 08:11:34 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBDebugger(std::move(debugger_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBDebugger);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp) {
|
2021-12-17 13:02:21 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBWatchpoint(std::move(watchpoint_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBWatchpoint);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp) {
|
2021-12-17 13:02:21 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBBreakpointLocation(std::move(bp_loc_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBBreakpointLocation);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp) {
|
2021-12-17 13:02:21 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBExecutionContext(std::move(ctx_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBExecutionContext);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::TypeImplSP type_impl_sp) {
|
2022-10-11 00:44:06 -07:00
|
|
|
return ToSWIGHelper(new lldb::SBType(type_impl_sp), SWIGTYPE_p_lldb__SBType);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(const TypeSummaryOptions &summary_options) {
|
2021-12-17 13:02:21 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBTypeSummaryOptions(summary_options),
|
|
|
|
|
SWIGTYPE_p_lldb__SBTypeSummaryOptions);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(const SymbolContext &sym_ctx) {
|
2021-12-17 13:02:21 +01:00
|
|
|
return ToSWIGHelper(new lldb::SBSymbolContext(sym_ctx),
|
|
|
|
|
SWIGTYPE_p_lldb__SBSymbolContext);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp) {
|
2023-03-03 15:17:59 -08:00
|
|
|
return ToSWIGHelper(new lldb::ProcessLaunchInfoSP(std::move(launch_info_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBLaunchInfo);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp) {
|
2023-03-03 15:17:59 -08:00
|
|
|
return ToSWIGHelper(new lldb::ProcessAttachInfoSP(std::move(attach_info_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBAttachInfo);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 16:31:27 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(lldb::DataExtractorSP data_sp) {
|
2023-03-03 19:30:56 -08:00
|
|
|
return ToSWIGHelper(new lldb::DataExtractorSP(std::move(data_sp)),
|
|
|
|
|
SWIGTYPE_p_lldb__SBData);
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-20 14:36:27 +01:00
|
|
|
ScopedPythonObject<lldb::SBCommandReturnObject>
|
2023-05-08 16:31:27 -07:00
|
|
|
SWIGBridge::ToSWIGWrapper(CommandReturnObject &cmd_retobj) {
|
2021-12-20 14:36:27 +01:00
|
|
|
return ScopedPythonObject<lldb::SBCommandReturnObject>(
|
|
|
|
|
new lldb::SBCommandReturnObject(cmd_retobj),
|
|
|
|
|
SWIGTYPE_p_lldb__SBCommandReturnObject);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-29 10:43:33 -08:00
|
|
|
ScopedPythonObject<lldb::SBEvent> SWIGBridge::ToSWIGWrapper(Event *event) {
|
|
|
|
|
return ScopedPythonObject<lldb::SBEvent>(new lldb::SBEvent(event),
|
|
|
|
|
SWIGTYPE_p_lldb__SBEvent);
|
2021-12-20 14:36:27 +01:00
|
|
|
}
|
|
|
|
|
|
2023-06-18 22:05:54 -07:00
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(
|
|
|
|
|
std::unique_ptr<lldb::SBFileSpec> file_spec_sb) {
|
|
|
|
|
return ToSWIGHelper(file_spec_sb.release(), SWIGTYPE_p_lldb__SBFileSpec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PythonObject SWIGBridge::ToSWIGWrapper(
|
|
|
|
|
std::unique_ptr<lldb::SBModuleSpec> module_spec_sb) {
|
|
|
|
|
return ToSWIGHelper(module_spec_sb.release(), SWIGTYPE_p_lldb__SBModuleSpec);
|
|
|
|
|
}
|
|
|
|
|
|
[lldb] Fix [some] leaks in python bindings
Using an lldb_private object in the bindings involves three steps
- wrapping the object in it's lldb::SB variant
- using swig to convert/wrap that to a PyObject
- wrapping *that* in a lldb_private::python::PythonObject
Our SBTypeToSWIGWrapper was only handling the middle part. This doesn't
just result in increased boilerplate in the callers, but is also a
functionality problem, as it's very hard to get the lifetime of of all
of these objects right. Most of the callers are creating the SB object
(step 1) on the stack, which means that we end up with dangling python
objects after the function terminates. Most of the time this isn't a
problem, because the python code does not need to persist the objects.
However, there are legitimate cases where they can do it (and even if
the use case is not completely legitimate, crashing is not the best
response to that).
For this reason, some of our code creates the SB object on the heap, but
it has another problem -- it never gets cleaned up.
This patch begins to add a new function (ToSWIGWrapper), which does all
of the three steps, while properly taking care of ownership. In the
first step, I have converted most of the leaky code (except for
SBStructuredData, which needs a bit more work).
Differential Revision: https://reviews.llvm.org/D114259
2021-11-18 21:27:27 +01:00
|
|
|
} // namespace python
|
|
|
|
|
} // namespace lldb_private
|