Closed tokjun closed 11 months ago
Slicer crashes when it receives an RTS_TDATA message. The problem can be reproduced using a modified TrackingDataServer example, which sends an RTS_TDATA message when the client requests to stop tracking. The modified example is available under the test_rts_tdata
branch in my repo
To build and start the modified TrackingData
$ git clone -b test_rts_tdata https://github.com/tokjun/OpenIGTLink.git
$ mkdir OpenIGTLink-build
$ cd OpenIGTLink-build
$ cmake -DBUILD_EXAMPLES:BOOL=TRUE ../OpenIGTLink
$ cd bin
$ ./TrackingDataServer 18944
Once the server has started, open 3D Slicer (SlicerOpenIGTLink module must be installed), and open IGT->OpenIGTLink
. Create a client connector node, and connect to localhost:18944
. If the connector becomes active successfully, open the IGT->OpenIGTLink Remote
, choose the created connector node, click Start
, and then click Stop
. At this point, Slicer sends a STP_TDATA message to the server. In response, the server stops tracking and sends back an RTS_TDATA message, which causes a Slicer crash.
Here's the backtrace (the line numbers might be different from the current version):
Thread 1 "SlicerApp-real" received signal SIGSEGV, Segmentation fault.
0x00007fff7c53c94c in igtl::MessageBase::UnpackBody (this=0x55555bf92350, crccheck=1, r=@0x7fffffffd0a4: 0) at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink-build/OpenIGTLink/Source/igtlMessageBase.cxx:906
(gdb) bt
#0 0x00007fff7c53c94c in igtl::MessageBase::UnpackBody(int, int&) (this=0x55555bf92350, crccheck=1, r=@0x7fffffffd0a4: 0)
at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink-build/OpenIGTLink/Source/igtlMessageBase.cxx:906
#1 0x00007fff7c53bee5 in igtl::MessageBase::Unpack(int) (this=0x55555bf92350, crccheck=1)
at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink-build/OpenIGTLink/Source/igtlMessageBase.cxx:618
#2 0x00007fff7c20f7c6 in igtlioTrackingDataConverter::fromIGTL(igtl::SmartPointer<igtl::MessageBase>, igtlioBaseConverter::HeaderData*, igtlioTrackingDataConverter::ContentData*, bool, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<IANA_ENCODING_TYPE, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::pair<IANA_ENCODING_TYPE, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >&)
(source=..., header=0x55555bf8d540, dest=0x55555bf8d5c0, checkCRC=true, outMetaInfo=std::map with 0 elements)
at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink-build/OpenIGTLinkIO/Converter/igtlioTrackingDataConverter.cxx:33
#3 0x00007fff7c28bdea in igtlioTrackingDataDevice::ReceiveIGTLMessage(igtl::SmartPointer<igtl::MessageBase>, bool) (this=0x55555bf8d4f0, buffer=..., checkCRC=true)
at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink-build/OpenIGTLinkIO/Devices/igtlioTrackingDataDevice.cxx:73
#4 0x00007fff7c3185bc in igtlioConnector::ImportDataFromCircularBuffer() (this=0x55555ad5d990)
at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink-build/OpenIGTLinkIO/Logic/igtlioConnector.cxx:773
#5 0x00007fff7c318cb2 in igtlioConnector::PeriodicProcess() (this=0x55555ad5d990)
at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink-build/OpenIGTLinkIO/Logic/igtlioConnector.cxx:837
#6 0x00007fff7c3e9f63 in vtkMRMLIGTLConnectorNode::PeriodicProcess() (this=0x55555c1257c0)
at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink/OpenIGTLinkIF/MRML/vtkMRMLIGTLConnectorNode.cxx:2542
#7 0x00007fff7c60ca33 in vtkSlicerOpenIGTLinkIFLogic::CallConnectorTimerHander() (this=0x5555586867f0)
at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink/OpenIGTLinkIF/Logic/vtkSlicerOpenIGTLinkIFLogic.cxx:336
#8 0x00007fff7c683db4 in qSlicerOpenIGTLinkIFModule::importDataAndEvents() (this=0x55555820a2f0)
at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink/OpenIGTLinkIF/qSlicerOpenIGTLinkIFModule.cxx:219
#9 0x00007fff7c68598a in qSlicerOpenIGTLinkIFModule::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
(_o=0x55555820a2f0, _c=QMetaObject::InvokeMetaMethod, _id=3, _a=0x7fffffffd7d0)
at /home/junichi/slicer/Modules-dev/SlicerOpenIGTLink-build/inner-build/OpenIGTLinkIF/moc_qSlicerOpenIGTLinkIFModule.cpp:90
#10 0x00007ffff58f17c8 in () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#11 0x00007ffff58f57fe in QTimer::timeout(QTimer::QPrivateSignal) () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#12 0x00007ffff58e733f in QObject::event(QEvent*) () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#13 0x00007ffff656c713 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt5Widgets.so.5
#14 0x00007ffff78ec562 in qSlicerApplication::notify(QObject*, QEvent*) (this=0x7fffffffdd30, receiver=0x5555581daaa0, event=0x7fffffffda00)
at /home/junichi/slicer/Slicer/Base/QTGUI/qSlicerApplication.cxx:518
#15 0x00007ffff58b9e3a in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#16 0x00007ffff59123eb in QTimerInfoList::activateTimers() () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#17 0x00007ffff5912cec in () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#18 0x00007fffd2f1bd3b in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#19 0x00007fffd2f71258 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#20 0x00007fffd2f193e3 in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#21 0x00007ffff59130b8 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#22 0x00007ffff58b875b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#23 0x00007ffff58c0cf4 in QCoreApplication::exec() () at /lib/x86_64-linux-gnu/libQt5Core.so.5
#24 0x00007ffff6d121a6 in qSlicerCoreApplication::exec() () at /home/junichi/slicer/Slicer/Base/QTCore/qSlicerCoreApplication.cxx:1049
#25 0x000055555555d1f1 in (anonymous namespace)::SlicerAppMain(int, char**) (argc=1, argv=0x7fffffffdec8) at /home/junichi/slicer/Slicer/Applications/SlicerApp/Main.cxx:63
#26 0x000055555555d341 in main(int, char**) (argc=1, argv=0x7fffffffdec8) at /home/junichi/slicer/Slicer/Base/QTApp/qSlicerApplicationMainWrapper.cxx:56
(gdb)
The issue seems to be related to how igtlioConnector::ImportDataFromCircularBuffer() in the OpenIGTLinkIO library is implemented.
When an RTS_TDATA message is received, igtlioConnector::ImportDataFromCircularBuffer() creates an igtlioDevice instance based on the "base type name," which is TDATA, not RTS_TDATA. ImportDataFromCircularBuffer() then calls igtlioTrackingDataDevice::ReceiveIGTLMessage(), where the received message (RTS_TDATA) is copied into an igtl::TrackingDataMessage class instance (transMsg) (Line 29). This can destroy transMsg, and cause SIGSEGV in the subsequent lines.
The issue has been resolved with the latest IGSIO/OpenIGTLinkIO.
3D Slicer crashed after connecting to Brainlab via OpenIGTLink and clicking the "Start" button on the OpenIGTLink Remote module.