ContextBrowserView: Fix deadlock
ClosedPublic

Authored by kfunk on Jan 27 2016, 8:55 AM.

Details

Summary

This happens everytime the context browser view is open at startup, and
KDevelop's background parser starts jobs.

Arguably, we should never block indefinitely in a non-user initiated event (here:
QWidget::showEvent). So let's give up after a timeout.

0  0x00007f16e48edc4d in nanosleep () at
../sysdeps/unix/syscall-template.S:81
1  0x00007f16e55e407d in qt_nanosleep (amount=...) at
tools/qelapsedtimer_unix.cpp:185
2  0x00007f16e5532ea4 in QThread::usleep (usecs=<optimized out>) at
thread/qthread_unix.cpp:475
3  0x00007f16e2dccf75 in KDevelop::DUChainLock::lockForRead(unsigned
int) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformLanguage.so.10
4  0x00007f16e2dcd3bb in KDevelop::DUChainReadLocker::lock() () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformLanguage.so.10
5  0x00007f16e2dcd35c in
KDevelop::DUChainReadLocker::DUChainReadLocker(KDevelop::DUChainLock*,
unsigned int) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformLanguage.
so.10
6  0x00007f16bc03c94b in ContextBrowserView::showEvent(QShowEvent*) ()
from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/plugins/kdevplatform/24/kdevcontextbrowser.so
7  0x00007f16e61a59f8 in QWidget::event (this=0x5947810,
event=0x7ffed94335e0) at kernel/qwidget.cpp:9044
8  0x00007f16bc03c907 in ContextBrowserView::event(QEvent*) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/plugins/kdevplatform/24/kdevcontextbrowser.so
9  0x00007f16e61629dc in QApplicationPrivate::notify_helper
(this=this@entry=0xd1f7f0, receiver=receiver@entry=0x5947810,
e=e@entry=0x7ffed94335e0) at kernel/qapplication.cpp:3716
10 0x00007f16e6167ea6 in QApplication::notify (this=0x7ffed9436e90,
receiver=0x5947810, e=0x7ffed94335e0) at kernel/qapplication.cpp:3499
11 0x00007f16e5714d7b in QCoreApplication::notifyInternal
(this=0x7ffed9436e90, receiver=receiver@entry=0x5947810,
event=event@entry=0x7ffed94335e0) at kernel/qcoreapplication.cpp:965
12 0x00007f16e61a2506 in QCoreApplication::sendEvent
(event=0x7ffed94335e0, receiver=0x5947810) at
../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:224
13 QWidgetPrivate::show_helper (this=0x59478b0) at
kernel/qwidget.cpp:7822
14 0x00007f16e61a20d6 in QWidgetPrivate::show_recursive
(this=<optimized out>) at kernel/qwidget.cpp:7693
15 0x00007f16e61a21f6 in QWidgetPrivate::showChildren
(this=this@entry=0x5b620e0, spontaneous=spontaneous@entry=false) at
kernel/qwidget.cpp:8189
16 0x00007f16e61a228f in QWidgetPrivate::show_helper
(this=this@entry=0x5b620e0) at kernel/qwidget.cpp:7769
17 0x00007f16e61a5085 in QWidget::setVisible (this=0x5b62080,
visible=<optimized out>) at kernel/qwidget.cpp:8108
18 0x00007f16e62901e8 in QDockWidgetPrivate::setWindowState
(this=this@entry=0x5b620e0, floating=floating@entry=false,
unplug=unplug@entry=false, rect=...) at widgets/qdockwidget.cpp:1046
19 0x00007f16e6290fc1 in QDockWidget::setFloating
(this=this@entry=0x5b62080, floating=floating@entry=false) at
widgets/qdockwidget.cpp:1269
20 0x00007f16e629ef75 in QDockAreaLayoutInfo::restoreState
(this=<optimized out>, stream=..., widgets=<empty>,
testing=testing@entry=false) at widgets/qdockarealayout.cpp:1979
21 0x00007f16e629f259 in QDockAreaLayout::restoreState
(this=this@entry=0x137ff28, stream=..., _dockwidgets=Python Exception
<class 'AttributeError'> 'NoneType' object has no attribute 'fi
nd':
, testing=testing@entry=false) at widgets/qdockarealayout.cpp:2320
22 0x00007f16e62c075a in QMainWindowLayoutState::restoreState
(this=this@entry=0x137fe50, _stream=..., oldState=...) at
widgets/qmainwindowlayout.cpp:685
23 0x00007f16e62c1e11 in QMainWindowLayout::restoreState
(this=0x137fe30, stream=...) at widgets/qmainwindowlayout.cpp:1924
24 0x00007f16e62bad6d in QMainWindow::restoreState
(this=this@entry=0x1216940,
state="\000\000\000\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\000\000\003\002\000\000\000\0
04\000\000\000\030\000C\000l\000a\000s\000s\000e\000s\000_\000c\000o\000d\000e\000\000\000\000C\000\000\000\000\000\000\001\000\000\003\000\000\000\034\000D\000o\000c\000u\000m\000e\000n\00
0t\000s\000_\000c\000o\000d\000e\000\000\000\002T\000\000\000\000\000\000l\001\000\000\003\000\000\000\036\000F\000i\000l\000e\000s\000y\000s\000t\000e\000m\000_\000c\000o\000d\000e\000\000
\000\000C\000\000\001\000\000\000b\001\000\000\003\000\000\000\032\000P\000r\000o\000j\000e\000c\000t\000s"...
= {...}, version=version@entry=0) at widgets/qmainwindow.cpp:1281
25 0x00007f16e8f08d11 in KMainWindow::applyMainWindowSettings
(this=this@entry=0x1216940, cg=...) at ../../src/kmainwindow.cpp:671
26 0x00007f16e8f41fd2 in KXmlGuiWindow::applyMainWindowSettings
(this=0x1216940, config=...) at ../../src/kxmlguiwindow.cpp:374
27 0x00007f16ea95d6b9 in
KDevelop::MainWindow::applyMainWindowSettings(KConfigGroup const&) ()
from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformShell.so.10
28 0x00007f16e8f41fa1 in KXmlGuiWindow::finalizeGUI (this=0x1216940) at
../../src/kxmlguiwindow.cpp:367
29 0x00007f16e8f354f3 in KXMLGUIFactory::addClient (this=0x11ffc10,
client=0x191ced0) at ../../src/kxmlguifactory.cpp:301
30 0x00007f16ea967a5f in
KDevelop::MainWindowPrivate::addPlugin(KDevelop::IPlugin*) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformShell.so.10
31 0x00007f16ea965aae in
QtPrivate::FunctorCall<QtPrivate::IndexesList<0>,
QtPrivate::List<KDevelop::IPlugin*>, void, void
(KDevelop::MainWindowPrivate::*)(KDevelop::IPlugin*)>::call(void
(KDevelop::MainWindowPrivate::*)(KDevelop::IPlugin*),
KDevelop::MainWindowPrivate*, void**) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformShell.so.10
32 0x00007f16ea965a10 in void QtPrivate::FunctionPointer<void
(KDevelop::MainWindowPrivate::*)(KDevelop::IPlugin*)>::call<QtPrivate::List<KDevelop::IPlugin*>,
void>(void (KDevelop::MainWin
dowPrivate::*)(KDevelop::IPlugin*), KDevelop::MainWindowPrivate*,
void**) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformShell.so.10
33 0x00007f16ea965938 in QtPrivate::QSlotObject<void
(KDevelop::MainWindowPrivate::*)(KDevelop::IPlugin*),
QtPrivate::List<KDevelop::IPlugin*>, void>::impl(int,
QtPrivate::QSlotObjectBase*
, QObject*, void**, bool*) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformShell.so.10
34 0x00007f16e5743777 in QtPrivate::QSlotObjectBase::call
(a=0x7ffed94342a0, r=0x13e3d10, this=<optimized out>) at
../../include/QtCore/../../src/corelib/kernel/qobject_impl.h:124
35 QMetaObject::activate (sender=0x12147d0, signalOffset=<optimized
out>, local_signal_index=<optimized out>, argv=<optimized out>) at
kernel/qobject.cpp:3698
36 0x00007f16eabbbdaf in
KDevelop::IPluginController::pluginLoaded(KDevelop::IPlugin*) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformInterfaces.so.10
37 0x00007f16ea97247e in
KDevelop::PluginController::loadPluginInternal(QString const&) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformShell.so.10
38 0x00007f16ea976004 in
KDevelop::PluginController::allPluginsForExtension(QString const&,
QMap<QString, QVariant> const&)::$_8::operator()(KPluginMetaData const&)
const () from /home/kfu
nk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformShell.so.10
39 0x00007f16ea974825 in void
KDevelop::PluginControllerPrivate::foreachEnabledPlugin<KDevelop::PluginController::allPluginsForExtension(QString
const&, QMap<QString, QVariant> const&)::$_
8>(KDevelop::PluginController::allPluginsForExtension(QString const&,
QMap<QString, QVariant> const&)::$_8, QString const&, QMap<QString,
QVariant> const&, QString const&) () from /home/kfu
nk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformShell.so.10
40 0x00007f16ea97457e in
KDevelop::PluginController::allPluginsForExtension(QString const&,
QMap<QString, QVariant> const&) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPla
tformShell.so.10
41 0x00007f16ea9d2745 in
KDevelop::LanguageController::languagesForMimetype(QString const&) ()
from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformShell.so.10
42 0x00007f16ea9d2503 in
KDevelop::LanguageController::languagesForUrl(QUrl const&) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformShell.so.10
43 0x00007f16e2d2c7e0 in
KDevelop::BackgroundParserPrivate::createParseJob(KDevelop::IndexedString
const&, KDevelop::TopDUContext::Features, QList<QPointer<QObject> >
const&, int) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformLanguage.so.10
44 0x00007f16e2d2594b in
KDevelop::BackgroundParserPrivate::parseDocumentsInternal() () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformLanguage.so.10
45 0x00007f16e2d22d14 in KDevelop::BackgroundParser::parseDocuments()
() from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformLanguage.so.10
46 0x00007f16e2f0b60f in
KDevelop::BackgroundParser::qt_static_metacall(QObject*,
QMetaObject::Call, int, void**) () from
/home/kfunk/opt/kdevelop/lib/x86_64-linux-gnu/libKDevPlatformLangu
age.so.10
47 0x00007f16e57447b1 in QObject::event (this=0x300b370, e=<optimized
out>) at kernel/qobject.cpp:1239

Diff Detail

Repository
R33 KDevPlatform
Branch
production
Lint
Lint Skipped
Unit
Unit Tests Skipped
kfunk updated this revision to Diff 2114.Jan 27 2016, 8:55 AM
kfunk retitled this revision from to ContextBrowserView: Fix deadlock.
kfunk updated this object.
kfunk edited the test plan for this revision. (Show Details)
Restricted Application added a subscriber: kdevelop-devel. · View Herald TranscriptJan 27 2016, 8:55 AM
kfunk updated this object.Jan 27 2016, 8:55 AM
brauch added a subscriber: brauch.Jan 27 2016, 10:48 AM

Looks sensible to me, but I wonder why it doesn't get the lock at some point ...?

In D866#16805, @brauch wrote:

Looks sensible to me, but I wonder why it doesn't get the lock at some point ...?

I'm missing the backtraces for the other threads, sorry. And of course I can't reproduce it anymore... I remember at least one QmlJS or Clang parse job holding the DUChain lock as well.

I've seen this deadlock several times in KDevelop, for what it's worth. This fix makes sense nevertheless (we shouldn't wait a significant amount of time in a widget event).

mwolff accepted this revision.Jan 28 2016, 3:00 PM
mwolff added a reviewer: mwolff.
mwolff added a subscriber: mwolff.

While this does fix the bug you linked to, I would not close it yet. The problem I describe there is still valid and could easily come back - loading plugins at that point can be very hazardous.

Also, I'd decrease the timeout to ~250ms or similar. 1s is already too much, imo.

This revision is now accepted and ready to land.Jan 28 2016, 3:00 PM
kfunk closed this revision.Jan 29 2016, 9:05 AM

Already merged:

commit e4c26c563231fea20898c1f3a9743b178df9fd39
Author: Kevin Funk <kfunk@kde.org>
Date: Wed Jan 27 08:36:22 2016 +0100

ContextBrowserView: Fix deadlock

This happens everytime the context browser view is open at startup, and
KDevelop's background parser starts jobs.

Arguably, we should never block indefinitely in a non-user initiated event (here:
QWidget::showEvent). So let's give up after a timeout.

Differential Revision: https://phabricator.kde.org/D866
CCBUG: 355100