Segmentation fault. Loguru caught a signal: SIGSEGV

Hello,
My c++ code can export data to .vtu file. I tried to visualize some result via paraview. However, when I click “Apply”, paraview closed itself. Could anyone give me some suggestions on how to solve it?
Thank you!

Paraview version: 5.10.1-11 (openmpi version)
System: Arch Linux
VTU File:
testOutput.vtu (654.2 KB)

Loguru caught a signal: SIGSEGV
Stack trace:
53      0x558c4f506b65 /opt/paraview/bin/paraview(+0xbb65) [0x558c4f506b65]
52      0x7fcb10df234a __libc_start_main + 138
51      0x7fcb10df2290 /usr/lib/libc.so.6(+0x23290) [0x7fcb10df2290]
50      0x558c4f505a2c /opt/paraview/bin/paraview(+0xaa2c) [0x558c4f505a2c]
49      0x7fcb0f090269 QCoreApplication::exec() + 153
48      0x7fcb0f08573c QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 300
47      0x7fcb0f0d7c4c QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 108
46      0x7fcb08f15132 g_main_context_iteration + 50
45      0x7fcb08f6d299 /usr/lib/libglib-2.0.so.0(+0xac299) [0x7fcb08f6d299]
44      0x7fcb08f1687b g_main_context_dispatch + 411
43      0x7fcae912f710 /usr/lib/libQt5XcbQpa.so.5(+0x64710) [0x7fcae912f710]
42      0x7fcb0f528995 QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 181
41      0x7fcb0f53f16c QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) + 1772
40      0x7fcb0f08cf98 QCoreApplication::notifyInternal2(QObject*, QEvent*) + 296
39      0x7fcb10378b1c QApplicationPrivate::notify_helper(QObject*, QEvent*) + 156
38      0x7fcb103cf15e /usr/lib/libQt5Widgets.so.5(+0x1cf15e) [0x7fcb103cf15e]
37      0x7fcb103cd3b5 /usr/lib/libQt5Widgets.so.5(+0x1cd3b5) [0x7fcb103cd3b5]
36      0x7fcb1037c337 QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) + 471
35      0x7fcb0f08cf98 QCoreApplication::notifyInternal2(QObject*, QEvent*) + 296
34      0x7fcb1037e339 QApplication::notify(QObject*, QEvent*) + 5033
33      0x7fcb10378b1c QApplicationPrivate::notify_helper(QObject*, QEvent*) + 156
32      0x7fcb103af6e7 QWidget::event(QEvent*) + 2759
31      0x7fcb10460470 QAbstractButton::mouseReleaseEvent(QMouseEvent*) + 192
30      0x7fcb104602cd /usr/lib/libQt5Widgets.so.5(+0x2602cd) [0x7fcb104602cd]
29      0x7fcb1045ed8a /usr/lib/libQt5Widgets.so.5(+0x25ed8a) [0x7fcb1045ed8a]
28      0x7fcb1045c527 QAbstractButton::clicked(bool) + 71
27      0x7fcb0f0bdc00 /usr/lib/libQt5Core.so.5(+0x2bdc00) [0x7fcb0f0bdc00]
26      0x7fcb0ffdef82 pqPropertiesPanel::apply() + 946
25      0x7fcb0fee2147 pqPropertiesPanel::applied(pqProxy*) + 71
24      0x7fcb0f0bdc00 /usr/lib/libQt5Core.so.5(+0x2bdc00) [0x7fcb0f0bdc00]
23      0x7fcb10ae50b9 pqApplyBehavior::applied(pqPropertiesPanel*, pqProxy*) + 249
22      0x7fcb10ae7d36 pqApplyBehavior::showData(pqPipelineSource*, pqView*) + 1878
21      0x7fcb0fd6c009 pqRenderViewBase::resetDisplay(bool) + 73
20      0x7fcb095ede18 vtkSMRenderViewProxy::ResetCamera(bool) + 280
19      0x7fcb0eaae628 vtkPVSessionBase::ExecuteStream(unsigned int, vtkClientServerStream const&, bool) + 120
18      0x7fcb0eaaf0a8 vtkPVSessionCore::ExecuteStreamInternal(vtkClientServerStream const&, bool) + 264
17      0x7fcb0fb074d6 vtkClientServerInterpreter::ProcessStream(vtkClientServerStream const&) + 38
16      0x7fcb0fb06fd8 vtkClientServerInterpreter::ProcessOneMessage(vtkClientServerStream const&, int) + 200
15      0x7fcb0fb06717 vtkClientServerInterpreter::ProcessCommandInvoke(vtkClientServerStream const&, int) + 1303
14      0x7fcb09b614a9 vtkPVRenderViewCommand(vtkClientServerInterpreter*, vtkObjectBase*, char const*, vtkClientServerStream const&, vtkClientServerStream&, void*) + 12841
13      0x7fcb09598653 vtkPVRenderView::ResetCamera() + 35
12      0x7fcb0959c83e vtkPVRenderView::Update() + 142
11      0x7fcb095ba5d2 vtkPVView::Update() + 290
10      0x7fcb095b58e1 vtkPVView::CallProcessViewRequest(vtkInformationRequestKey*, vtkInformation*, vtkInformationVector*) + 145
9       0x7fcb09532c37 vtkGeometryRepresentationWithFaces::ProcessViewRequest(vtkInformationRequestKey*, vtkInformation*, vtkInformation*) + 23
8       0x7fcb09531473 vtkGeometryRepresentation::ProcessViewRequest(vtkInformationRequestKey*, vtkInformation*, vtkInformation*) + 227
7       0x7fcb09531363 vtkGeometryRepresentation::ComputeVisibleDataBounds() + 115
6       0x7fcb0952dccd vtkGeometryRepresentation::GetBounds(vtkDataObject*, double*, vtkCompositeDataDisplayAttributes*) + 77
5       0x7fcb0dabab8b vtkCompositeDataDisplayAttributes::ComputeVisibleBounds(vtkCompositeDataDisplayAttributes*, vtkDataObject*, double*) + 107
4       0x7fcb0daba9db vtkCompositeDataDisplayAttributes::ComputeVisibleBoundsInternal(vtkCompositeDataDisplayAttributes*, vtkDataObject*, vtkBoundingBox*, bool) + 491
3       0x7fcb0dabaade vtkCompositeDataDisplayAttributes::ComputeVisibleBoundsInternal(vtkCompositeDataDisplayAttributes*, vtkDataObject*, vtkBoundingBox*, bool) + 750
2       0x7fcb0c6fadb6 vtkPolyData::GetCellsBounds(double*) + 22
1       0x7fcb0c70b0df /opt/paraview/bin/../lib/libvtkCommonDataModel.so.1(+0x30b0df) [0x7fcb0c70b0df]
0       0x7fcb10e07a00 /usr/lib/libc.so.6(+0x38a00) [0x7fcb10e07a00]
(  13.103s) [paraview        ]                       :0     FATL| Signal: SIGSEGV
Segmentation fault (core dumped)

There are 2 scenarios, either the data are not written properly, or there is a vtk bug in vtkPolyData::GetCellsBounds. Would you mind providing us with a summary of your data and also write them in ascii format?

Even if there is an issue with the data, ComputeCellBounds should not deallocate when nothing was allocated.

Thread 1 "paraview" received signal SIGABRT, Aborted.
0x00007ffff7e3d64c in ?? () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff7e3d64c in ?? () from /usr/lib/libc.so.6
#1  0x00007ffff7ded958 in raise () from /usr/lib/libc.so.6
#2  0x00007ffff7dd753d in abort () from /usr/lib/libc.so.6
#3  0x00007ffff7e317ee in ?? () from /usr/lib/libc.so.6
#4  0x00007ffff7e473dc in ?? () from /usr/lib/libc.so.6
#5  0x00007ffff7e4937c in ?? () from /usr/lib/libc.so.6
#6  0x00007ffff7e4bba3 in free () from /usr/lib/libc.so.6
#7  0x00007ffff06ac2ac in vtkPolyData::ComputeCellsBounds (this=0x55555f4eba00) at /home/glow/dev/paraview/pv1/src/VTK/Common/DataModel/vtkPolyData.cxx:526
#8  0x00007ffff06ac30a in vtkPolyData::GetCellsBounds (this=0x55555f4eba00, bounds=0x7fffffffc440) at /home/glow/dev/paraview/pv1/src/VTK/Common/DataModel/vtkPolyData.cxx:53l4                                                                                                                                                                            e
#9  0x00007ffff350e520 in vtkCompositeDataDisplayAttributes::ComputeVisibleBoundsInternal (cda=0x55555f577070, dobj=0x55555f4eba00, bbox=0x7fffffffc5a0, parentVisible=true) at /home/glow/dev/paraview/pv1/src/VTK/Rendering/Core/vtkCompositeDataDisplayAttributes.cxx:334
#10 0x00007ffff350e45e in vtkCompositeDataDisplayAttributes::ComputeVisibleBoundsInternal (cda=0x55555f577070, dobj=0x55555f923240, bbox=0x7fffffffc5a0, parentVisible=true) -at /home/glow/dev/paraview/pv1/src/VTK/Rendering/Core/vtkCompositeDataDisplayAttributes.cxx:323                                                                              s
#11 0x00007ffff350e2a0 in vtkCompositeDataDisplayAttributes::ComputeVisibleBounds (cda=0x55555f577070, dobj=0x55555f923240, bounds=0x5555556c8e58) at /home/glow/dev/paraviewi/pv1/src/VTK/Rendering/Core/vtkCompositeDataDisplayAttributes.cxx:297                                                                                                        i
#12 0x00007fffec3b1d42 in vtkGeometryRepresentation::GetBounds (dataObject=0x55555f923240, bounds=0x5555556c8e58, cdAttributes=0x55555f577070) at /home/glow/dev/paraview/pv1/src/Remoting/Views/vtkGeometryRepresentation.cxx:552
#13 0x00007fffec3b6222 in vtkGeometryRepresentation::ComputeVisibleDataBounds (this=0x5555556c8ca0) at /home/glow/dev/paraview/pv1/src/Remoting/Views/vtkGeometryRepresentation.cxx:1570
#14 0x00007fffec3b14ac in vtkGeometryRepresentation::ProcessViewRequest (this=0x5555556c8ca0, request_type=0x5555556d9390, inInfo=0x5555579ffd30, outInfo=0x55555f921800) at /home/glow/dev/paraview/pv1/src/Remoting/Views/vtkGeometryRepresentation.cxx:404
#15 0x00007fffec3c156f in vtkGeometryRepresentationWithFaces::ProcessViewRequest (this=0x5555556c8ca0, request_type=0x5555556d9390, inInfo=0x5555579ffd30, outInfo=0x55555f92l1800) at /home/glow/dev/paraview/pv1/src/Remoting/Views/vtkGeometryRepresentationWithFaces.cxx:62                                                                            e
#16 0x00007fffec53b073 in vtkPVView::CallProcessViewRequest (this=0x555557d387e0, type=0x5555556d9390, inInfo=0x5555579ffd30, outVec=0x5555579c0850) at /home/glow/dev/paraview/pv1/src/Remoting/Views/vtkPVView.cxx:582

Hello,

Sorry for the late reply and thank you for your help!

I fixed the problem, the reason is because I give the wrong point index to the connectivity element.

Hello,

Thank you for your help!

I solved the problem by assigning correct point index to the connectivity element. Maybe that’s the reason related to the ComputeCellBounds. By the way, may I ask what does the ComputeCellBounds do?

It can extract the bounds of only the points that are used by the cells of the dataset.

If you were writing wrong ids (probably out of bounds), it makes sense for the segfault to occur, because you were accessing out of bounds information.

An error would be excepted, a segfault is not acceptable and should be fixed imo.

Well to get an error in the following code:

        for (vtkIdType cellId = 0; cellId < numCells; ++cellId)
        {
          cellArray->GetCellAtId(cellId, npts, pts, cellPointIds);
          for (ptIdx = 0; ptIdx < npts; ++ptIdx)
          {
            ptUses[pts[ptIdx]] = 1;
          }
        }

we would have to add a check if pts[ptIdx]] < numPts. As you can see this will add a significant overhead to the computation. There are multiple checks above such:

    if (numPDCells <= 0)
    {
      vtkMath::UninitializeBounds(this->CellsBounds);
      return;
    }
    if (this->Points == nullptr || numPts <= 0)
    {
      vtkMath::UninitializeBounds(this->CellsBounds);
      return;
    }

Which can catch a lot of special cases, but we can’t assume at every single step of an algorithm that an error might occur, otherwise performance will be severely degraded.

but we can’t assume at every single step of an algorithm that an error might occur, otherwise performance will be severely degraded.

Correct, this should be checked earlier in the I/O code, not in computing code.

With my correctness hat on, i have to agree with you. With my performance hat on and knowing the 99% of the time the data are correct. i will have to argue that this is not the right thing to do, at least all the time. Maybe a DataSet Validator filter that each reader could execute optionally or execute the validator outside the reader would be the way to go.

I’m pretty sure I can make a very fast test in the code, but maybe a better way would be to test if `pts[ptIdx]] < numPts’ only in debug builds?

With regards to speed, the for loop itself is horrible - and slow. Any idea what npts is generally? 1, or 4, or 9?

It doesn’t really matter. Used-in-production software are not supposed to segfault, ever.

I agree, Mathieu. Further, I believe the call to GetCellAtId isn’t exactly fast. I would say we just add the check.

GetCellAtId has been highly optimized to not even perform a copy if possible.

I also agree with the statement that used-in-production software is not supposed to segfault, ever.

I will repeat to make my point clear. Algorithms that are designed for the highest possible performance should not be deteriorated to perform error checking of input. If we were to do this here, i would argue that we should do everywhere that GetCellAtId is used throught VTK/ParaView. As you can imagine this will reduce the performance of many algorithms.

If we want a solution to this problem, we could avoid this error by performing a check at the I/O stage as @mwestphal suggested. We could use the vtkCellArray::IsValid function and also check that the maximum/minimum ids in the connectivity array make sense wrt to the number of points. This could happen at the end of every I/O reader that produces a vtkPolyData/vtkUnsturcturedGrid/vtkExplicitStructuredGrid. Would you agree to something like that?

@wascott @cory.quammen thoughts?

This makes sense to me. Note that readers are frequently bottle-necked by IO. That is why we spent so much time trying to figure out how to not read more than needed for Exodus files. My guess is that IO will be vastly larger than sanity checks of the data.

1 Like

Sounds like a good idea to add an option in ParaView general settings which validates the output vtk dataobject of all readers. We can leave it enabled by default - so no more segfault for corrupt connectivity. However, for scripts, or repeated runs it’s up to users to disable the sanity checks when the datasets are known to be correct.

It’s more common for the input of a VTK algorithm (output of a reader) to be wrong rather than the output of a VTK algorithm, but it would be beneficial to test both.

Interesting. Didn’t think of validating the output of a ParaView filter in general. But I can see how it is beneficial. There are a few times when ParaView segfaults while computing the volume/surface representation from the output of a filter. I’m sure you know of a way to multithread the dataset validation procedures. How much of an overhead will it be?

I don’t think it’s going to be significant enough. IO will always be the bottleneck especially if you just want to parse your vtkCellArray only once…