MRtrix3 / mrtrix3

MRtrix3 provides a set of tools to perform various advanced diffusion MRI analyses, including constrained spherical deconvolution (CSD), probabilistic tractography, track-density imaging, and apparent fibre density
http://www.mrtrix.org
Mozilla Public License 2.0
290 stars 178 forks source link

mrview: Connectome tool segfault for dense parcellations #2421

Open Lestropie opened 2 years ago

Lestropie commented 2 years ago

Encountering this issue when initialising the connectome tool with an image that contains a large number of parcels. Reproduced from user data.

The segfault occurs inconsistently, sometimes occurring on different lines of code (binding new buffers or passing data to them) and for different edges. There does not appear to be anything wrong with the input data. My suspicion is that because I am generating individual buffers for each edge, with a large number of codes comes a large number of edges and I'm exceeding some kind of internal limitation on buffer count. If that's the case, the solution would be to resolve all edge graphical data into centralised buffers, and change a lot of code so that things like highlighting and masking are done in GLSL, which is a fairly large change.

Thread 1 "mrview" received signal SIGSEGV, Segmentation fault.
0x00007fffe90bd2ec in ?? () from /usr/lib/dri/iris_dri.so
(gdb) bt
#0  0x00007fffe90bd2ec in  () at /usr/lib/dri/iris_dri.so
#1  0x00007fffe8600177 in  () at /usr/lib/dri/iris_dri.so
#2  0x00007fffe86962b0 in  () at /usr/lib/dri/iris_dri.so
#3  0x00007fffe86963c1 in  () at /usr/lib/dri/iris_dri.so
#4  0x000055555581f8f4 in MR::GUI::MRView::Tool::Edge::Line::Line(MR::GUI::MRView::Tool::Edge const&) (this=0x55555b83bd30, parent=...) at src/gui/mrview/tool/connectome/edge.cpp:117
#5  0x000055555581eff3 in MR::GUI::MRView::Tool::Edge::Edge(unsigned int, unsigned int, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) (this=0x7fffffffb6b0, one=163, two=167, c_one=..., c_two=...)
    at src/gui/mrview/tool/connectome/edge.cpp:50
#6  0x00005555559782a6 in MR::GUI::MRView::Tool::Connectome::initialise(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (this=0x555556ad8110, 
    path="/home/rob/MRI_data/sina_mrview/native.dMRI_space.Glasser.mif") at src/gui/mrview/tool/connectome/connectome.cpp:2307
#7  0x000055555597a475 in MR::GUI::MRView::Tool::Connectome::image_open_slot() (this=0x555556ad8110) at src/gui/mrview/tool/connectome/connectome.cpp:874
#8  0x0000555555962f76 in MR::GUI::MRView::Tool::Connectome::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=0x555556ad8110, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7fffffffc310)
    at tmp/src/gui/mrview/tool/connectome/connectome_moc.cpp:236
#9  0x00007ffff5a067e0 in  () at /usr/lib/libQt5Core.so.5
#10 0x00007ffff67425e3 in QAbstractButton::clicked(bool) () at /usr/lib/libQt5Widgets.so.5
#11 0x00007ffff674286c in  () at /usr/lib/libQt5Widgets.so.5
#12 0x00007ffff6744474 in  () at /usr/lib/libQt5Widgets.so.5
#13 0x00007ffff6744695 in QAbstractButton::mouseReleaseEvent(QMouseEvent*) () at /usr/lib/libQt5Widgets.so.5
#14 0x00007ffff668e0be in QWidget::event(QEvent*) () at /usr/lib/libQt5Widgets.so.5
#15 0x00007ffff664ad62 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/libQt5Widgets.so.5
#16 0x00007ffff6652ac9 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/libQt5Widgets.so.5
#17 0x00007ffff59cf3fa in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/libQt5Core.so.5
#18 0x00007ffff665157b in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) () at /usr/lib/libQt5Widgets.so.5
#19 0x00007ffff66a7a84 in  () at /usr/lib/libQt5Widgets.so.5
#20 0x00007ffff66aadb5 in  () at /usr/lib/libQt5Widgets.so.5
#21 0x00007ffff664ad62 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/libQt5Widgets.so.5
#22 0x00007ffff59cf3fa in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/libQt5Core.so.5
#23 0x00007ffff5f4e1f0 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () at /usr/lib/libQt5Gui.so.5
#24 0x00007ffff5f237d5 in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt5Gui.so.5
#25 0x00007ffff1ae8fcc in  () at /usr/lib/libQt5XcbQpa.so.5
#26 0x00007ffff43124dc in g_main_context_dispatch () at /usr/lib/libglib-2.0.so.0
#27 0x00007ffff4366799 in  () at /usr/lib/libglib-2.0.so.0
#28 0x00007ffff430fbc1 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
#29 0x00007ffff5a28026 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt5Core.so.5
#30 0x00007ffff59cdd6c in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt5Core.so.5
#31 0x00007ffff59d62d4 in QCoreApplication::exec() () at /usr/lib/libQt5Core.so.5
#32 0x0000555555b43e95 in run() () at cmd/mrview.cpp:103
#33 0x0000555555b439ec in main(int, char**) (cmdline_argc=4, cmdline_argv=0x7fffffffe0a8) at ./core/command.h:101
Lestropie commented 2 years ago

Backtrace might be a little bit of a red herring. Here's an error with a parcellation with fewer nodes, but still enough to generate an error:

#0  0x00007fffe90d7159 in  () at /usr/lib/dri/iris_dri.so
#1  0x00007fffe9252989 in  () at /usr/lib/dri/iris_dri.so
#2  0x00007fffe90c0fd2 in  () at /usr/lib/dri/iris_dri.so
#3  0x00007fffe90c1bc6 in  () at /usr/lib/dri/iris_dri.so
#4  0x00007fffe8aaa06f in  () at /usr/lib/dri/iris_dri.so
#5  0x00007fffe8aad3d2 in  () at /usr/lib/dri/iris_dri.so
#6  0x00007fffe94e1433 in  () at /usr/lib/dri/iris_dri.so
#7  0x00007fffe8abd974 in  () at /usr/lib/dri/iris_dri.so
#8  0x00007fffe86153d4 in  () at /usr/lib/dri/iris_dri.so
#9  0x00007fffe8615f33 in  () at /usr/lib/dri/iris_dri.so
#10 0x00007fffe87b3a31 in  () at /usr/lib/dri/iris_dri.so
#11 0x00007fffe87b3b0e in  () at /usr/lib/dri/iris_dri.so
#12 0x00007ffff5f8805d in  () at /usr/lib/libQt5Gui.so.5
#13 0x00007ffff5f883f1 in  () at /usr/lib/libQt5Gui.so.5
#14 0x00007ffff629d5f3 in QPlatformBackingStore::composeAndFlush(QWindow*, QRegion const&, QPoint const&, QPlatformTextureList*, bool) () at /usr/lib/libQt5Gui.so.5
#15 0x00007ffff1adf329 in  () at /usr/lib/libQt5XcbQpa.so.5
#16 0x00007ffff66583d4 in  () at /usr/lib/libQt5Widgets.so.5
#17 0x00007ffff665a2d3 in  () at /usr/lib/libQt5Widgets.so.5
#18 0x00007ffff665c303 in  () at /usr/lib/libQt5Widgets.so.5
#19 0x00007ffff668e829 in QWidget::event(QEvent*) () at /usr/lib/libQt5Widgets.so.5
#20 0x00007ffff664ad62 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/libQt5Widgets.so.5
#21 0x00007ffff59cf3fa in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/libQt5Core.so.5
#22 0x00007ffff59d24f9 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () at /usr/lib/libQt5Core.so.5
#23 0x00007ffff5a289f4 in  () at /usr/lib/libQt5Core.so.5
#24 0x00007ffff43124dc in g_main_context_dispatch () at /usr/lib/libglib-2.0.so.0
#25 0x00007ffff4366799 in  () at /usr/lib/libglib-2.0.so.0
#26 0x00007ffff430fbc1 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
#27 0x00007ffff5a28026 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt5Core.so.5
#28 0x00007ffff59cdd6c in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt5Core.so.5
#29 0x00007ffff59d62d4 in QCoreApplication::exec() () at /usr/lib/libQt5Core.so.5
#30 0x0000555555b43e95 in run() () at cmd/mrview.cpp:103
#31 0x0000555555b439ec in main(int, char**) (cmdline_argc=2, cmdline_argv=0x7fffffffe0c8) at ./core/command.h:101

For me the problem kicks in for any parcellation image with at least 254 nodes, which to me is suspiciously close to 2^8.

Also, if the edge geometry were to be centrally resolved, it would make sense for the same thing to be done for nodes. So for both aspects of the network, individual nodes / edges would index into these central arrays, data related to visual control (e.g. transparency, masking, control of colour, etc.) would be updated and buffers re-sent to GPU as required in order for only two draw calls to be required (one for nodes, one for edges).