[Lldb-commits] [PATCH] D77480: Fix illegal early call to PyBuffer_Release in swig typemaps

Lawrence D'Anna via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Sat Apr 4 20:14:45 PDT 2020


lawrence_danna created this revision.
lawrence_danna added reviewers: labath, jasonmolenda, JDevlieghere, vadimcn.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.
lawrence_danna added a comment.

thanks @vadimcn  for pointing this out.


The buffer protocol does not allow us to just call PyBuffer_Release
and assume the buffer will still be there.   Most things that implement the
buffer protocol will let us get away with that, but not all.   We need
to release it at the end of the SWIG wrapper.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77480

Files:
  lldb/bindings/python/python-typemaps.swig


Index: lldb/bindings/python/python-typemaps.swig
===================================================================
--- lldb/bindings/python/python-typemaps.swig
+++ lldb/bindings/python/python-typemaps.swig
@@ -488,39 +488,51 @@
     }
 }
 
+%inline %{
+
+class Py_buffer_RAII {
+public:
+  Py_buffer m_buffer = {};
+  ~Py_buffer_RAII() {
+    if (m_buffer.obj)
+      PyBuffer_Release(&m_buffer);
+  }
+};
+
+%}
+
 // These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i,
 // and fixed so they will not crash if PyObject_GetBuffer fails.
 // https://github.com/swig/swig/issues/1640
+//
+// I've also moved the call to PyBuffer_Release to the end of the SWIG wrapper, 
+// doing it right away is not legal according to the python buffer protocol.
 
 %define %pybuffer_mutable_binary(TYPEMAP, SIZE)
-%typemap(in) (TYPEMAP, SIZE) {
+%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
   int res; Py_ssize_t size = 0; void *buf = 0;
-  Py_buffer view;
-  res = PyObject_GetBuffer($input, &view, PyBUF_WRITABLE);
+  res = PyObject_GetBuffer($input, &view.m_buffer, PyBUF_WRITABLE);
   if (res < 0) {
     PyErr_Clear();
     %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
   }
-  size = view.len;
-  buf = view.buf;
-  PyBuffer_Release(&view);
+  size = view.m_buffer.len;
+  buf = view.m_buffer.buf;
   $1 = ($1_ltype) buf;
   $2 = ($2_ltype) (size/sizeof($*1_type));
 }
 %enddef
 
 %define %pybuffer_binary(TYPEMAP, SIZE)
-%typemap(in) (TYPEMAP, SIZE) {
+%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
   int res; Py_ssize_t size = 0; const void *buf = 0;
-  Py_buffer view;
-  res = PyObject_GetBuffer($input, &view, PyBUF_CONTIG_RO);
+  res = PyObject_GetBuffer($input, &view.m_buffer, PyBUF_CONTIG_RO);
   if (res < 0) {
     PyErr_Clear();
     %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
   }
-  size = view.len;
-  buf = view.buf;
-  PyBuffer_Release(&view);
+  size = view.m_buffer.len;
+  buf = view.m_buffer.buf;
   $1 = ($1_ltype) buf;
   $2 = ($2_ltype) (size / sizeof($*1_type));
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D77480.255100.patch
Type: text/x-patch
Size: 2049 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20200405/e8b79f17/attachment.bin>


More information about the lldb-commits mailing list