[vtkusers] Segmentation fault on quit when using vtkProgrammableFilter wtih Python

Todd Gamblin tgamblin at cs.unc.edu
Mon Sep 22 18:13:41 EDT 2008


I've got a simple vtk pipeline written in Python that I want to use to 
visualize a bunch of surfaces.  I made a custom callback class with an 
internal vtkProgrammableFilter, and everything is fine at runtime 
(things render, I can interact w/them, etc.).  However, I'm getting a 
segmentation fault on quit under Linux, and on Mac OS X, it hangs for a 
bit and gives me a bus error.

I think this is because I'm passing a local function object to my 
vtkProgrammableFilter, but I'm not sure what the best way to get around 
that is.  If I pass a global function, I don't get this error (e.g. I 
can run the expCos.py example just fine).  I've attached the code that 
gets me this error, along with output fromvalgrind that shows that the 
segfault is occurring in vtkPythonVoidFuncArgDelete() inside 
vtkProgrammableFilter().  If I take the vtkProgrammableFilter() out of 
the pipeline entirely, the segfault goes away.

Any help or suggestions would be appreciated.

-Todd Gamblin



Valgrind output (from time of segfault):
> ==31788== Invalid read of size 4
> ==31788==    at 0x40C75EF: PyThreadState_New (pystate.c:199)
> ==31788==    by 0x40C76E2: PyGILState_Ensure (pystate.c:565)
> ==31788==    by 0x474E429: vtkPythonVoidFuncArgDelete(void*) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommonPythonD.so.5.3.0)
> ==31788==    by 0x6C1AE3A: 
> vtkProgrammableFilter::~vtkProgrammableFilter() (in 
> /home/gamblin1/src/vtk-build/bin/libvtkGraphics.so.5.3.0)
> ==31788==    by 0x49C6955: 
> vtkObjectBase::UnRegisterInternal(vtkObjectBase*, int) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x49C4F70: 
> vtkObject::UnRegisterInternal(vtkObjectBase*, int) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x49686A0: 
> vtkGarbageCollectorToObjectBaseFriendship::UnRegister(vtkObjectBase*, 
> vtkObjectBase*) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x4966B92: 
> vtkGarbageCollectorImpl::CollectComponent(vtkGarbageCollectorImpl::ComponentType*) 
> (in /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x4965E3E: 
> vtkGarbageCollectorImpl::CollectInternal(vtkObjectBase*) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x4967BAA: 
> vtkGarbageCollector::Collect(vtkObjectBase*) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)==31788==    by 
> 0x49C696B: vtkObjectBase::UnRegisterInternal(vtkObjectBase*, int) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x49C4F70: 
> vtkObject::UnRegisterInternal(vtkObjectBase*, int) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==  Address 0x4 is not stack'd, malloc'd or (recently) free'd
> ==31788==
> ==31788== Process terminating with default action of signal 11 (SIGSEGV)
> ==31788==  Access not within mapped region at address 0x4
> ==31788==    at 0x40C75EF: PyThreadState_New (pystate.c:199)
> ==31788==    by 0x40C76E2: PyGILState_Ensure (pystate.c:565)
> ==31788==    by 0x474E429: vtkPythonVoidFuncArgDelete(void*) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommonPythonD.so.5.3.0)
> ==31788==    by 0x6C1AE3A: 
> vtkProgrammableFilter::~vtkProgrammableFilter() (in 
> /home/gamblin1/src/vtk-build/bin/libvtkGraphics.so.5.3.0)
> ==31788==    by 0x49C6955: 
> vtkObjectBase::UnRegisterInternal(vtkObjectBase*, int) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x49C4F70: 
> vtkObject::UnRegisterInternal(vtkObjectBase*, int) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x49686A0: 
> vtkGarbageCollectorToObjectBaseFriendship::UnRegister(vtkObjectBase*, 
> vtkObjectBase*) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x4966B92: 
> vtkGarbageCollectorImpl::CollectComponent(vtkGarbageCollectorImpl::ComponentType*) 
> (in /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x4965E3E: 
> vtkGarbageCollectorImpl::CollectInternal(vtkObjectBase*) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x4967BAA: 
> vtkGarbageCollector::Collect(vtkObjectBase*) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)==31788==    by 
> 0x49C696B: vtkObjectBase::UnRegisterInternal(vtkObjectBase*, int) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==    by 0x49C4F70: 
> vtkObject::UnRegisterInternal(vtkObjectBase*, int) (in 
> /home/gamblin1/src/vtk-build/bin/libvtkCommon.so.5.3.0)
> ==31788==

Python code (vtkEffortRegion() is an implicit function that I've 
implemented myself in C++ and wrapped):
> class Surface:
>     def __init__(self, actor, fun, lastStage):
>         self.actor = actor
>         self.fun = fun
>         self.lastStage = lastStage
>
>     def setColor(self, r,g,b):
>         self.actor.GetProperty().SetColor(r,g,b)
>
>     def GetDims(self, dims):
>         self.fun.GetDims(dims)
>
>     def GetRange(self, range):
>         self.fun.GetRange(range)
>
>     def GetOutput(self):
>         return self.lastStage.GetOutput()
>
>
> def create(names):
>     if not isinstance(names, list):
>         names = [names]
>
>     dims = zeros([6])
>     regions = [effort.get_region(name) for name in names]
>
>     fun = vtkEffortFunction()
>
>     fun.GetDims(dims)
>
>     sample = vtk.vtkSampleFunction()
>     sample.SetImplicitFunction(fun)
>     sample.SetSampleDimensions(75, 75, 25)
>     sample.SetModelBounds(dims)
>     sample.ComputeNormalsOff()
>
>     surface = vtk.vtkContourFilter()
>     surface.SetInputConnection(sample.GetOutputPort())
>     surface.SetValue(0, 0.0)
>     surface.ComputeScalarsOn()
>
>     scalars = vtk.vtkProgrammableFilter()
>     scalars.SetInputConnection(surface.GetOutputPort())
>
>     def computeScalars(filter):
>         input = scalars.GetPolyDataInput()
>         numPts = input.GetNumberOfPoints()
>         vals = vtk.vtkFloatArray()
>
>         for i in range(0, numPts):
>             x = input.GetPoint(i)
>             vals.InsertValue(i, x[2])
>
>         scalars.GetPolyDataOutput().GetPointData().SetScalars(vals)
>
>     scalars.SetExecuteMethod(computeScalars)
>
>     mapper = vtk.vtkPolyDataMapper()
>     mapper.SetInputConnection(scalars.GetOutputPort())
>     mapper.ScalarVisibilityOn()
>
>     actor = vtk.vtkActor()
>     actor.SetMapper(mapper)
>
>     return Surface(actor, fun, surface)





More information about the vtkusers mailing list