Crash in vtkPolyData.GetCell

I’m getting a seg fault when trying to extract a cut boundary…I think. I’m using Visual Studio and Python 3.8, which don’t work together yet, so I can see the cxx code at the point of failure, but have no idea how I got here.

The culprit code is in Common/DataModel/vtkPolyData.cxx, current head, lines 149…

vtkCell* vtkPolyData::GetCell(vtkIdType cellId)
{
  if (!this->Cells)
  {
    this->BuildCells();
  }

  const TaggedCellId tag = this->Cells->GetTag(cellId);

The polydata has four polys, apparently all degenerate, so down in BuildCells, it throws at line 932, catches at line 958, sets ‘this->Cells = nullptr’ and returns. Seg fault occurs immediately on the last line quoted above (and I see the same and similar patterns elsewhere in this file).

Should BuildCells be returning an ‘EmptyCells’, or should the GetCell code check for null and set ‘tag’ to some none-ish value, or ???

I’m trying to track down the root cause (why and where we’re producing a degenerate poly), but it seems like GetCell and friends should not be seg faulting like this.

Can you check if this has been already fixed in latest VTK master?

Hi Andras,

The above code snippet was cut from latest on github committed May 6, is that the master branch? (Or is it on gitlab or somewhere else?)

Eric

OK, if it is not fixed there then it would be a great help if you could submit a merge request with a test that reproduces the issue and a proposed fix. Details of of how to create merge request are described here: https://github.com/Kitware/VTK/blob/master/CONTRIBUTING.md.

There should be a message in the error log explaining why BuildCells failed. The line numbers seem to have changed slightly in the current master, but I think you’re hitting this condition:

https://gitlab.kitware.com/vtk/vtk/blob/master/Common/DataModel/vtkPolyData.cxx#L932-935

        if (size < 3)
        {
          throw std::runtime_error("Invalid cell size for polys.");
        }

This checks that all cells in the Polys cell array are defined with at least three points. The Polys cell array must only contain VTK_TRIANGLE, VTK_QUAD, or VTK_POLYGON cells, all of which require at least 3 points to be valid.

Can you verify that your polydata is correctly defined?

Is VTK now allowed to throw exceptions on its public interface?

I’m not sure if there’s a policy for that. We use them internally, but I can’t think of a place where they’re used in API.

These particular exceptions are just implementation details, and are always caught and handled before they would escape an API boundary by logging an error and discarding the exception:

https://gitlab.kitware.com/vtk/vtk/-/blob/master/Common/DataModel/vtkPolyData.cxx#L905-964

I came up with a reproducer this morning, it’s as you suspect, an invalid polygon:

#!/usr/bin/env python

import vtk
print(vtk.vtkVersion().GetVTKSourceVersion())

points = vtk.vtkPoints()
points.InsertNextPoint([1, 2, 3])
points.InsertNextPoint([4, 5, 6])

polys = vtk.vtkCellArray()
polys.InsertNextCell(2, [0, 1])  # Degenerate polygon.

polydata = vtk.vtkPolyData()
polydata.SetPoints(points)
polydata.SetPolys (polys)

cell = polydata.GetCell(0)

This causes a crash in 8.90 and 9.0, but doesn’t segfault in 8.2.

> ./degen_poly.py
9.0.0
2020-07-12 11:58:13.054 (   0.245s) [                ]        vtkPolyData.cxx:961    ERR| vtkPolyData (000001DDC46B8950): Error while constructing cell map: Invalid cell size for polys.
Segmentation fault

OK, internal use is no problem at all. Of course it would cause huge issues in VTK and in applications if uncaught exceptions leaked out.