<div dir="ltr">Oops! Thanks for finding this. I can cherry-pick your (pending) fix to<div>my python-py3k branch for VTK 6.3.<div><br></div><div> - David</div><div> <div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 18, 2015 at 1:34 PM, Ben Boeckel <span dir="ltr"><<a href="mailto:ben.boeckel@kitware.com" target="_blank">ben.boeckel@kitware.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Tue, Nov 17, 2015 at 12:53:09 +0100, Mathieu Westphal wrote:<br>
</span><span class="">> I'm testing my GIl ensured version of VTK (<br>
> <a href="https://gitlab.kitware.com/vtk/vtk/merge_requests/582" rel="noreferrer" target="_blank">https://gitlab.kitware.com/vtk/vtk/merge_requests/582</a>) with the buildbots,<br>
> and i have only three problematic recurring tests, on a specific build of<br>
> megas.<br>
<br>
</span>Found it. Here's the code from PyVTKObject_FromPointer:<br>
<br>
> const char *classname = vtkPythonUtil::StripModule(pytype->tp_name);<br>
<br>
...<br>
<br>
> // Use the vtkname of the supplied class type<br>
> PyObject *s = PyObject_GetAttrString((PyObject *)pytype, "__vtkname__");<br>
> if (s)<br>
> {<br>
> #ifdef VTK_PY3K<br>
> PyObject *tmp = PyUnicode_AsUTF8String(s);<br>
<br>
Python3 uses unicode objects, but we need ASCII...<br>
<br>
> if (tmp)<br>
> {<br>
> Py_DECREF(s);<br>
> s = tmp;<br>
<br>
...so `s` is now a new bytes object...<br>
<br>
> }<br>
> #endif<br>
> classname = PyBytes_AsString(s);<br>
<br>
...we take a pointer to its data for use later...<br>
<br>
> if (classname == 0)<br>
> {<br>
> Py_DECREF(s);<br>
> return NULL;<br>
> }<br>
> }<br>
> cls = vtkPythonUtil::FindClass(classname);<br>
> if (cls == 0)<br>
> {<br>
> PyErr_Format(PyExc_ValueError,<br>
> "internal error, unknown VTK class %.200s",<br>
> classname);<br>
> Py_XDECREF(s);<br>
> return NULL;<br>
> }<br>
> Py_XDECREF(s);<br>
<br>
...decref the bytes object here (which can now be garbage collected)...<br>
<br>
> }<br>
><br>
> if (!ptr)<br>
> {<br>
> // Create a new instance of this class since we were not given one.<br>
> if (cls->vtk_new)<br>
> {<br>
> ptr = cls->vtk_new();<br>
> if (!ptr)<br>
> {<br>
> // The vtk_new() method returns null when a factory class has no<br>
> // implementation (i.e. cannot provide a concrete class instance.)<br>
> // NotImplementedError indicates a pure virtual method call.<br>
> PyErr_SetString(<br>
> PyExc_NotImplementedError,<br>
> "no concrete implementation exists for this class");<br>
> return 0;<br>
> }<br>
> created = true;<br>
><br>
> // Check the type of the newly-created object<br>
> const char *newclassname = ptr->GetClassName();<br>
> if (strcmp(newclassname, classname) != 0)<br>
<br>
...and use the pointer to the old object's data here.<br>
<br>
It only crashes in Python3 and when the garbage collector runs between<br>
the Py_XDECREF above and its use here. The test fails because glibc<br>
catches the bogus pointer after free() does its thing, so that's why<br>
only megas caught it.<br>
<br>
Branch incoming :) .<br>
<div class="HOEnZb"><div class="h5"><br>
--Ben<br></div></div></blockquote></div></div></div></div></div></div>