[vtk-developers] Observer crashes with Python thread, bug in vtkPythonCommand and also in dataset_adapter

E. Tadeu e.tadeu at gmail.com
Tue Jun 16 14:26:37 EDT 2015


Currently, if an observer is added in a python thread and then executed in
another thread after the first one has finished, it will cause a
segfault/access violation in the python interpreter.

This code reproduces the problem:

    from Queue import Queue
    from threading import Thread
    import vtk


    def on_delete(caller, event):
        print 'on_delete:'
        print '    caller:', caller
        print '    event:', event


    def create_object_with_observer(result_queue):
        object_with_observer = vtk.vtkObject()
        object_with_observer.AddObserver('DeleteEvent', on_delete)

        result_queue.put(object_with_observer)


    def test_observer_command_with_threads():
        result_queue = Queue()

        thread = Thread(target=create_object_with_observer,
args=(result_queue,))
        thread.start()
        thread.join()

        object_with_observer = result_queue.get(block=True)
        print object_with_observer
        del object_with_observer  # <-- crashes here (would crash later
without del too)
        print 'checkpoint'


    if __name__ == '__main__':
        test_observer_command_with_threads()


This seems to happen because of this line in vtkPythonCommand.cxx, which
seems to be assigning a bad ThreadState pointer to _PyThreadState_Current:

    prevThreadState = PyThreadState_Swap(this->ThreadState);

(The pointer seems to be dangling. Perhaps vtkPythonCommand::SetThreadState
should *incref *the PyThreadState* object?)

This bug is directly affecting dataset_adapter, because it causes a crash
in this use case (dataset_adapter uses a command to store the numpy array
ref):

    from Queue import Queue
    from threading import Thread
    from vtk.numpy_interface.dataset_adapter import UnstructuredGrid
    import numpy
    import vtk


    def create_unstructured_grid(result_queue):
        points = numpy.array([[0.0, 0.0, 0.0]])
        ug = UnstructuredGrid(vtk.vtkUnstructuredGrid())
        ug.SetPoints(points)
        result_queue.put(ug)


    def test_unstructured_grid_in_thread():
        result_queue = Queue()
        thread = Thread(target=create_unstructured_grid,
args=(result_queue,))
        thread.start()
        thread.join()
        ug = result_queue.get(block=True)
        print ug
        del ug  # <-- crashes
        print 'checkpoint'


    if __name__ == '__main__':
        test_unstructured_grid_in_thread()


( I've already submitted a bug report here:
http://www.paraview.org/Bug/view.php?id=15545 )


  Best regards,
  Edson
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20150616/60da4eb8/attachment.html>


More information about the vtk-developers mailing list