[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