[vtk-developers] Gil tests on megas
    Ben Boeckel 
    ben.boeckel at kitware.com
       
    Wed Nov 18 15:34:46 EST 2015
    
    
  
On Tue, Nov 17, 2015 at 12:53:09 +0100, Mathieu Westphal wrote:
> I'm testing my GIl ensured version of VTK (
> https://gitlab.kitware.com/vtk/vtk/merge_requests/582) with the buildbots,
> and i have only three problematic recurring tests, on a specific build of
> megas.
Found it. Here's the code from PyVTKObject_FromPointer:
>   const char *classname = vtkPythonUtil::StripModule(pytype->tp_name);
...
>     // Use the vtkname of the supplied class type
>     PyObject *s = PyObject_GetAttrString((PyObject *)pytype, "__vtkname__");
>     if (s)
>       {
> #ifdef VTK_PY3K
>       PyObject *tmp = PyUnicode_AsUTF8String(s);
Python3 uses unicode objects, but we need ASCII...
>       if (tmp)
>         {
>         Py_DECREF(s);
>         s = tmp;
...so `s` is now a new bytes object...
>         }
> #endif
>       classname = PyBytes_AsString(s);
...we take a pointer to its data for use later...
>       if (classname == 0)
>         {
>         Py_DECREF(s);
>         return NULL;
>         }
>       }
>     cls = vtkPythonUtil::FindClass(classname);
>     if (cls == 0)
>       {
>       PyErr_Format(PyExc_ValueError,
>                    "internal error, unknown VTK class %.200s",
>                    classname);
>       Py_XDECREF(s);
>       return NULL;
>       }
>     Py_XDECREF(s);
...decref the bytes object here (which can now be garbage collected)...
>     }
> 
>   if (!ptr)
>     {
>     // Create a new instance of this class since we were not given one.
>     if (cls->vtk_new)
>       {
>       ptr = cls->vtk_new();
>       if (!ptr)
>         {
>         // The vtk_new() method returns null when a factory class has no
>         // implementation (i.e. cannot provide a concrete class instance.)
>         // NotImplementedError indicates a pure virtual method call.
>         PyErr_SetString(
>           PyExc_NotImplementedError,
>           "no concrete implementation exists for this class");
>         return 0;
>         }
>       created = true;
> 
>       // Check the type of the newly-created object
>       const char *newclassname = ptr->GetClassName();
>       if (strcmp(newclassname, classname) != 0)
...and use the pointer to the old object's data here.
It only crashes in Python3 and when the garbage collector runs between
the Py_XDECREF above and its use here. The test fails because glibc
catches the bogus pointer after free() does its thing, so that's why
only megas caught it.
Branch incoming :) .
--Ben
    
    
More information about the vtk-developers
mailing list