Mayavi: seg fault when screenshot of 3D plot

Created on 5 Sep 2018  ·  7Comments  ·  Source: enthought/mayavi

This file: minimal_example_fail.py:

import faulthandler
faulthandler.enable()

from mayavi import mlab
mlab.test_plot3d()
mlab.screenshot()

fails with the following stack:

$ python minimal_example_fail.py 
Fatal Python error: Segmentation fault

Current thread 0x00007f2c3107e740 (most recent call first):
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/tvtk/tvtk_base.py", line 568 in _wrap_call
  File "tvtk_classes/open_gl_render_window.py", line 79 in get_pixel_data
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/mayavi/tools/figure.py", line 348 in screenshot
  File "minimal_example_fail.py", line 15 in <module>
Segmentation fault (core dumped)

To reproduce:

$ conda deactivate
$ conda create -n test python=3.6 numpy "pyqt>=5" matplotlib traits pyface traitsui
$ conda activate test
$ pip install vtk
$ pip install mayavi
$ python minimal_example_fail.py

@larsoner @agramfort

Most helpful comment

Can you confirm that this modification fixes things?

from pyface.api import GUI
from mayavi import mlab
mlab.test_plot3d()
GUI().process_events()
mlab.screenshot()

Or a shell one-liner:

python -c "from pyface.api import GUI; from mayavi import mlab; mlab.test_plot3d(); GUI().process_events(); mlab.screenshot()"

Basically I suspect the problem is that the event loop is not started, and so the system is in some not-fully-rendered state when the screenshot is attempted.

We work around this in PySurfer by forcing rendering with this little GUI trick.

@prabhuramachandran assuming this does fix things, it's possible there is some way to check if the OpenGL contex (or some other thing) is actually valid before attempting the screenshot, and if it's not, use this trick / hack to process events so it becomes valid. Seems a bit iffy / too hacky, though, so maybe not worth it.

All 7 comments

I am not able to reproduce this but there is another issue that I run into. The issue is that the window has a zero size. This is really a Qt issue as the mainloop is not running. Can you try this on an IPython session with %gui qt and see?

Is this what you mean?

$ ipython 
Python 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 17:14:51) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: %gui qt

In [2]: %run ./minimal_example_fail.py
Qt WebEngine seems to be initialized from a plugin. Please set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute before constructing QGuiApplication.
Fatal Python error: Segmentation fault

Thread 0x00007fb7eef88700 (most recent call first):
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/threading.py", line 295 in wait
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/threading.py", line 551 in wait
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/history.py", line 829 in run
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/history.py", line 58 in needs_sqlite
  File "<decorator-gen-24>", line 2 in run
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/threading.py", line 916 in _bootstrap_inner
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/threading.py", line 884 in _bootstrap

Current thread 0x00007fb7f5710740 (most recent call first):
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/tvtk/tvtk_base.py", line 568 in _wrap_call
  File "tvtk_classes/open_gl_render_window.py", line 79 in get_pixel_data
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/mayavi/tools/figure.py", line 348 in screenshot
  File "/home/maximilien.chaumon/owncloud/Lab/Projects/CTPS/code/minimal_example_fail.py", line 15 in <module>
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/utils/py3compat.py", line 188 in execfile
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2527 in safe_execfile
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/magics/execution.py", line 761 in run
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/magics/execution.py", line 775 in run
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/magic.py", line 187 in <lambda>
  File "<decorator-gen-60>", line 2 in run
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2131 in run_line_magic
  File "<ipython-input-2-f514c016d8ee>", line 1 in <module>
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2963 in run_code
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2909 in run_ast_nodes
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2785 in _run_cell
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2662 in run_cell
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/terminal/interactiveshell.py", line 476 in interact
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/terminal/interactiveshell.py", line 485 in mainloop
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/terminal/ipapp.py", line 356 in start
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/traitlets/config/application.py", line 658 in launch_instance
  File "/home/maximilien.chaumon/anaconda3/envs/mne/lib/python3.6/site-packages/IPython/__init__.py", line 125 in start_ipython
  File "/home/maximilien.chaumon/anaconda3/envs/mne/bin/ipython", line 11 in <module>
Segmentation fault (core dumped)

I tried this on my ubuntu machine with VTK-8.1.1 (from pip), Python 3.6.0, mayavi master, pyqt5 5.10.1 and I get an error but no segfault. The error I am seeing is due to a deeper issue that without the UI toolkit running, there is no window open so the screen size is still zero but this does not segfault. I'll work on resolving the other issue with the size being zero but unfortunately, I am unable to reproduce your segfault.

I've encountered a similar if not the same segfault error on both OSX and Linux machines. I was able to narrow it down to a potential mayavi commit causing the error.

fd9a515a9563d81a42b84514c1fb4ce5f81ac9a0 is the first bad commit
commit fd9a515a9563d81a42b84514c1fb4ce5f81ac9a0
Author: Prabhu Ramachandran prabhu@aero.iitb.ac.in
Date: Fri Aug 3 21:38:13 2018 -0400

Modify module manager to work with composite data.

This uses the dataset_adapter code from VTK and requires VTK >= 6.3.

:04000004000088baad8a26a7fc9d06fc95979441b4cd436e26962eca99efb8a7de37c75d3113fe194c16403b269d M mayavi

Going to see if I can reproduce with minimal from @dnacombo
I can reproduce using the minimal example, but only on my Linux box.

Platform: Linux-4.15.0-34-generic-x86_64-with-debian-buster-sid
Python: 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 17:14:51) [GCC 7.2.0]
Executable: /home/ktavabi/miniconda3/envs/mne/bin/python
CPU: x86_64: 24 cores
Memory: 94.4 GB

mne: 0.17.dev0
numpy: 1.15.1 {blas=mkl_rt, lapack=mkl_rt}
scipy: 1.1.0
matplotlib: 2.2.2 {backend=Qt5Agg}

sklearn: 0.19.2
nibabel: 2.4.0dev
mayavi: 4.7.0.dev0 4.6.0 {qt_api=pyqt5}
cupy: Not found
pandas: 0.23.4
dipy: 0.15.0dev
vtk: 8.1.1

On my OSX machine I get different errors, but no segfault.

I encountered a similar/same segfault error on a different machine but very similar 18.04 build with following specs:

Platform: Linux-4.15.0-36-generic-x86_64-with-debian-buster-sid
Python: 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 17:14:51) [GCC 7.2.0]
Executable: /home/nordme/miniconda3/envs/mne/bin/python
CPU: x86_64: 12 cores
Memory: 15.5 GB

mne: 0.17.dev0
numpy: 1.15.2 {blas=mkl_rt, lapack=mkl_rt}
scipy: 1.1.0
matplotlib: 2.2.2 {backend=Qt5Agg}

sklearn: 0.20.0
nibabel: 2.3.0
mayavi: 4.7.0.dev0 {qt_api=pyqt5}
cupy: Not found
pandas: 0.23.4
dipy: 0.14.0

Switching to a19c710c3f61389d79ed05271584e44f9744f6bc 4.6.0 release resolved the error. LMK if you want to see the trace.

Can you confirm that this modification fixes things?

from pyface.api import GUI
from mayavi import mlab
mlab.test_plot3d()
GUI().process_events()
mlab.screenshot()

Or a shell one-liner:

python -c "from pyface.api import GUI; from mayavi import mlab; mlab.test_plot3d(); GUI().process_events(); mlab.screenshot()"

Basically I suspect the problem is that the event loop is not started, and so the system is in some not-fully-rendered state when the screenshot is attempted.

We work around this in PySurfer by forcing rendering with this little GUI trick.

@prabhuramachandran assuming this does fix things, it's possible there is some way to check if the OpenGL contex (or some other thing) is actually valid before attempting the screenshot, and if it's not, use this trick / hack to process events so it becomes valid. Seems a bit iffy / too hacky, though, so maybe not worth it.

@larsoner -- yes I figured the same thing (see my earlier comment) and want to fix it cleanly in mlab at some point. I am hoping to get to it at some point. Also, as of v 4.6.1, mlab has a process_ui_events function that calls process events without the user having to import GUI etc. (http://docs.enthought.com/mayavi/mayavi/auto/changes.html#id10).

Was this page helpful?
0 / 5 - 0 ratings