Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
Qt Creator 4.14.0
-
None
-
8fad758f6038875f5219c79fd35e937956e4c890 (qt-creator/qt-creator/4.15)
Description
To reproduce (more than 50% chances):
1. Prepare 2 different sessions containing creator project.
2. Load one of them.
3. Wait until "Parsing C/C++ Files" gets finished and open class view and expand some items there.
4. Switch the session to the second creator. Repeat the step 3 there.
5. Switch the session back. Now start observing the "Parsing C/C++ Files" progress. Prepare to the next session switch by opening "File | Session" menu and put your finger on the mouse button but don't press it yet - wait for the proper time. Be ready to trigger session switch at the right point in time.
6. Just after the "Parsing C/C++ Files" finished and got green, quickly trigger the session switch. The time frame window is quite narrow, about 1 second, so be prepared. The thing is that session switch should happen at the time when Class View starts parsing the project tree. This parsing lasts for max 1 second, so you should fit into this frame.
7. If you were unlucky, repeat steps 5 and 6 until you crash.
The stack trace from the crash looks like:
Thread 1 (Thread 0x7fb61bfff640 (LWP 20759)): #0 0x00007fb65d6aba70 in QIcon::isNull (this=0x60) at /home/jarek/dev/qt-515/qtbase/src/gui/image/qicon.cpp:993 #1 0x00007fb64115fdf4 in ProjectExplorer::FolderNode::icon (this=0x0) at /home/jarek/dev/creator-master/src/plugins/projectexplorer/projectnodes.cpp:491 #2 0x00007fb634a928d6 in ClassView::Internal::Parser::parse (this=0x1f1ef68) at /home/jarek/dev/creator-master/src/plugins/classview/classviewparser.cpp:309 #3 0x00007fb634a94314 in ClassView::Internal::Parser::emitCurrentTree (this=0x1f1ef68) at /home/jarek/dev/creator-master/src/plugins/classview/classviewparser.cpp:700 #4 0x00007fb634a942ac in ClassView::Internal::Parser::onResetDataDone (this=0x1f1ef68) at /home/jarek/dev/creator-master/src/plugins/classview/classviewparser.cpp:678 #5 0x00007fb634a8ebd4 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (ClassView::Internal::Parser::*)()>::call(void (ClassView::Internal::Parser::*)(), ClassView::Internal::Parser*, void**) (f=(void (ClassView::Internal::Parser::*)(ClassView::Internal::Parser * const)) 0x7fb634a94294 <ClassView::Internal::Parser::onResetDataDone()>, o=0x1f1ef68, arg=0x328d1f8) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qobjectdefs_impl.h:152 #6 0x00007fb634a8e70d in QtPrivate::FunctionPointer<void (ClassView::Internal::Parser::*)()>::call<QtPrivate::List<>, void>(void (ClassView::Internal::Parser::*)(), ClassView::Internal::Parser*, void**) (f=(void (ClassView::Internal::Parser::*)(ClassView::Internal::Parser * const)) 0x7fb634a94294 <ClassView::Internal::Parser::onResetDataDone()>, o=0x1f1ef68, arg=0x328d1f8) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qobjectdefs_impl.h:185 #7 0x00007fb634a8e187 in QtPrivate::QSlotObject<void (ClassView::Internal::Parser::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=1, this_=0x1f241b0, r=0x1f1ef68, a=0x328d1f8, ret=0x0) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qobjectdefs_impl.h:418 #8 0x00007fb65ce76d3f in QtPrivate::QSlotObjectBase::call (this=0x1f241b0, r=0x1f1ef68, a=0x328d1f8) at ../../include/QtCore/../../../../qt-515/qtbase/src/corelib/kernel/qobjectdefs_impl.h:398 #9 0x00007fb65cea7ea7 in QMetaCallEvent::placeMetaCall (this=0x328d1b0, object=0x1f1ef68) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qobject.cpp:615 #10 0x00007fb65cea8d14 in QObject::event (this=0x1f1ef68, e=0x328d1b0) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qobject.cpp:1314 #11 0x00007fb65df68859 in QApplicationPrivate::notify_helper (this=0x11bc480, receiver=0x1f1ef68, e=0x328d1b0) at /home/jarek/dev/qt-515/qtbase/src/widgets/kernel/qapplication.cpp:3632 #12 0x00007fb65df65d0f in QApplication::notify (this=0x7ffed5a480d0, receiver=0x1f1ef68, e=0x328d1b0) at /home/jarek/dev/qt-515/qtbase/src/widgets/kernel/qapplication.cpp:2972 #13 0x00007fb65ce65b68 in QCoreApplication::notifyInternal2 (receiver=0x1f1ef68, event=0x328d1b0) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qcoreapplication.cpp:1064 #14 0x00007fb65ce66500 in QCoreApplication::sendEvent (receiver=0x1f1ef68, event=0x328d1b0) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qcoreapplication.cpp:1462 #15 0x00007fb65ce671e8 in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x1f1f030) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qcoreapplication.cpp:1821 #16 0x00007fb65ce66b7a in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qcoreapplication.cpp:1680 #17 0x00007fb65cef4127 in postEventSourceDispatch (s=0x7fb61c000e30) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:277 #18 0x00007fb659b0396f in g_main_context_dispatch () from /lib64/libglib-2.0.so.0 #19 0x00007fb659b55758 in g_main_context_iterate.constprop () from /lib64/libglib-2.0.so.0 #20 0x00007fb659b00d43 in g_main_context_iteration () from /lib64/libglib-2.0.so.0 #21 0x00007fb65cef4850 in QEventDispatcherGlib::processEvents (this=0x7fb61c005250, flags=...) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:423 #22 0x00007fb65ce6263f in QEventLoop::processEvents (this=0x7fb61bffebe0, flags=...) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qeventloop.cpp:139 #23 0x00007fb65ce6294c in QEventLoop::exec (this=0x7fb61bffebe0, flags=...) at /home/jarek/dev/qt-515/qtbase/src/corelib/kernel/qeventloop.cpp:232 #24 0x00007fb65cbfa52f in QThread::exec (this=0x1f1ef80) at /home/jarek/dev/qt-515/qtbase/src/corelib/thread/qthread.cpp:547 #25 0x00007fb65cbfa6c2 in QThread::run (this=0x1f1ef80) at /home/jarek/dev/qt-515/qtbase/src/corelib/thread/qthread.cpp:616 #26 0x00007fb65cbfd30e in QThreadPrivate::start (arg=0x1f1ef80) at /home/jarek/dev/qt-515/qtbase/src/corelib/thread/qthread_unix.cpp:329 #27 0x00007fb65be953f9 in start_thread () from /lib64/libpthread.so.0 #28 0x00007fb65c701903 in clone () from /lib64/libc.so.6
Most probably the reason is that inside ParserTreeItem::ConstPtr Parser::parse() function, which is called from non-gui thread, we are calling SessionManager::projects(), which is not guaranteed to be thread safe. When we operate on the project inside the loop, it may happen, that after a call to SessionManager::projects(), the returned projects already get deleted by the main thread (because of session switch), while we are still taking data out of them (like prj->containerNode()->icon(), which is called after the project gets parsed).
Attachments
Issue Links
- relates to
-
QTCREATORBUG-25301 Creator uses QIcons in non-gui threads
- Closed
For Gerrit Dashboard: QTCREATORBUG-25312 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
334859,3 | ClassView: Fix a crash when switching sessions | master | qt-creator/qt-creator | Status: MERGED | +2 | 0 |
336882,9 | ClassView: Fix a possible crash on session switch | 4.15 | qt-creator/qt-creator | Status: MERGED | +2 | 0 |