DevHeads.net

attica_kde.so closing crash

Hey all,

I recently fixed attica's plugin loading so it now finds and loads the
attica_kde.so plugin but when applications using knewstuff (and thus
attica) close it's giving a segfault when the PlatformDependent object is
destructed. I've not done much at all with plugins in the past, but I've
never seen a backtrace like this and thought someone else on this list must
have and would know how to fix it or what's going wrong.

To test I'm running khotnewstuff (from knewstuff tests folder) and on
closing the dialog I'm getting this backtrace from the segfault.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff720057e in
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>::~QExplicitlySharedDataPointer
(this=0xa13810, __in_chrg=<optimized out>)
at
../../include/QtCore/../../../../qt5/qtbase/src/corelib/tools/qshareddata.h:156

156 inline ~QExplicitlySharedDataPointer() { if (d &&
!d->ref.deref()) delete d; }
(gdb) bt
#0 0x00007ffff720057e in
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>::~QExplicitlySharedDataPointer
(this=0xa13810, __in_chrg=<optimized out>)
at
../../include/QtCore/../../../../qt5/qtbase/src/corelib/tools/qshareddata.h:156

#1 0x00007ffff71ff978 in QNetworkConfiguration::~QNetworkConfiguration
(this=0xa13810, __in_chrg=<optimized out>)
at
/home/jeremy/devel/kde/src/qt5/qtbase/src/network/bearer/qnetworkconfiguration.cpp:304

#2 0x00007ffff71bd9e1 in
QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate (this=0xa13740,
__in_chrg=<optimized out>)
at
/home/jeremy/devel/kde/src/qt5/qtbase/src/network/access/qnetworkaccessmanager.cpp:1488

#3 0x00007ffff71bda6c in
QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate (this=0xa13740,
__in_chrg=<optimized out>)
at
/home/jeremy/devel/kde/src/qt5/qtbase/src/network/access/qnetworkaccessmanager.cpp:1499

#4 0x00007ffff4e63c70 in QScopedPointerDeleter<QObjectData>::cleanup
(pointer=0xa13740) at
../../include/QtCore/../../../../qt5/qtbase/src/corelib/tools/qscopedpointer.h:54

#5 0x00007ffff4e6225b in QScopedPointer<QObjectData,
QScopedPointerDeleter<QObjectData> >::~QScopedPointer (this=0xa13008,
__in_chrg=<optimized out>)
at
../../include/QtCore/../../../../qt5/qtbase/src/corelib/tools/qscopedpointer.h:101

#6 0x00007ffff4e577db in QObject::~QObject (this=0xa13000,
__in_chrg=<optimized out>) at
/home/jeremy/devel/kde/src/qt5/qtbase/src/corelib/kernel/qobject.cpp:882
#7 0x00007ffff71bae03 in QNetworkAccessManager::~QNetworkAccessManager
(this=0xa13000, __in_chrg=<optimized out>)
at
/home/jeremy/devel/kde/src/qt5/qtbase/src/network/access/qnetworkaccessmanager.cpp:466

#8 0x00007ffff38e4ba5 in KIO::AccessManager::~AccessManager
(this=0xa13000, __in_chrg=<optimized out>) at
/home/jeremy/devel/kde/src/frameworks/kio/src/widgets/accessmanager.cpp:121
#9 0x00007ffff38e4bd4 in KIO::AccessManager::~AccessManager
(this=0xa13000, __in_chrg=<optimized out>) at
/home/jeremy/devel/kde/src/frameworks/kio/src/widgets/accessmanager.cpp:126
#10 0x00007ffff4e59150 in QObjectPrivate::deleteChildren (this=0xa12a10) at
/home/jeremy/devel/kde/src/qt5/qtbase/src/corelib/kernel/qobject.cpp:1950
#11 0x00007ffff4e57768 in QObject::~QObject (this=0xa0eff0,
__in_chrg=<optimized out>) at
/home/jeremy/devel/kde/src/qt5/qtbase/src/corelib/kernel/qobject.cpp:1030
#12 0x00007fffd95e77ce in
Attica::KdePlatformDependent::~KdePlatformDependent (this=0xa0eff0,
__in_chrg=<optimized out>)
at
/home/jeremy/devel/kde/src/kde/workspace/plasma-desktop/attica-kde/kdeplugin/kdeplatformdependent.cpp:58

#13 0x00007fffd95e7806 in
Attica::KdePlatformDependent::~KdePlatformDependent (this=0xa0eff0,
__in_chrg=<optimized out>)
at
/home/jeremy/devel/kde/src/kde/workspace/plasma-desktop/attica-kde/kdeplugin/kdeplatformdependent.cpp:61

#14 0x00007ffff4e10947 in QLibraryPrivate::unload (this=0xa02f50,
flag=QLibraryPrivate::NoUnloadSys) at
/home/jeremy/devel/kde/src/qt5/qtbase/src/corelib/plugin/qlibrary.cpp:548
#15 0x00007ffff4e1240d in QLibraryStore::cleanup () at
/home/jeremy/devel/kde/src/qt5/qtbase/src/corelib/plugin/qlibrary.cpp:394
#16 0x00007ffff4e10449 in qlibraryCleanup () at
/home/jeremy/devel/kde/src/qt5/qtbase/src/corelib/plugin/qlibrary.cpp:418
#17 0x00007ffff4e10467 in (anonymous
namespace)::qlibraryCleanup_dtor_class_::~qlibraryCleanup_dtor_class_
(this=0x7ffff510cf11 <(anonymous
namespace)::qlibraryCleanup_dtor_instance_>,
__in_chrg=<optimized out>) at
/home/jeremy/devel/kde/src/qt5/qtbase/src/corelib/plugin/qlibrary.cpp:420
#18 0x00007ffff3fad60f in __cxa_finalize () from /usr/lib/libc.so.6
#19 0x00007ffff4bc7e53 in __do_global_dtors_aux () from
/home/jeremy/devel/kde/src/qt5build/qtbase/lib/libQt5Core.so.5
#20 0x00007fffffffe140 in ?? ()
#21 0x00007ffff7dea817 in _dl_fini () from /lib64/ld-linux-x86-64.so.2
Backtrace stopped: frame did not save the PC

If I change KDEPlatformDependent to keep a QNetworkAccessManager instead of
the KIO::AccessManager it doesn't segfault (but I guess we lose the kio
desktop integration in thep process) Any idea what is going on here?

thanks,
Jeremy

Comments

Re: attica_kde.so closing crash

By =?utf-8?Q?Thoma... at 11/16/2014 - 19:33

On Sonntag, 16. November 2014 21:50:03 CEST, Jeremy Whiting wrote:
You do not happen to delete a bechilded member in the destructor explicitly, are you?

Ie, sth. like

KdePlatformDependent() : QObject() {
m_accessmanager = new AccessManager(this);
}

~KdePlatformDependent() {
delete m_accessmanager;
}

Cheers,
Thomas

Re: attica_kde.so closing crash

By Albert Astals Cid at 11/16/2014 - 19:38

El Dilluns, 17 de novembre de 2014, a les 00:33:17, Thomas Lübking va
escriure:
Why would this be wrong?

Cheers,
Albert

Re: attica_kde.so closing crash

By =?utf-8?Q?Thoma... at 11/17/2014 - 09:50

"Nothing"*

*in general, but:

bool QCoreApplication::notify() {
// no events are delivered after ~QCoreApplication() has started
if (QCoreApplicationPrivate::is_app_closing)
return true;
...
}

Since deleting children in the deconstructor is completely pointless and I /have/ seen things go south (style ...plugin!), so my rule of thumb is to leave moc alone and do not delete child members in destructors.

(Also since in addition, the glib dispatcher apparently has a tendency to defer events by one cycle)

I don't say "this is it!", but, quelle surprise:

QNetworkAccessManager::~QNetworkAccessManager()
{
#ifndef QT_NO_NETWORKPROXY
delete d_func()->proxyFactory;
#endif

// Delete the QNetworkReply children first.
// Else a QAbstractNetworkCache might get deleted in ~QObject
// before a QNetworkReply that accesses the QAbstractNetworkCache
// object in its destructor.
qDeleteAll(findChildren<QNetworkReply *>());
// The other children will be deleted in this ~QObject
// FIXME instead of this "hack" make the QNetworkReplyImpl
// properly watch the cache deletion, e.g. via a QWeakPointer.
}

Jeremy, my wild shot in the dark would be to find all QNetworkReply children of m_accessManager, list them, check if there are some ;-), reparent them (to "0") and delete them in the deconstructor. If that "fixes" it, maybe this needs to be moved into the KIO AccessManager (as a temp workaround Qt)

Cheers,
Thomas

Re: attica_kde.so closing crash

By Jeremy Paul Whiting at 11/17/2014 - 12:59

Thomas,

Thanks for the pointer. I tried changing KIO::AccessManager's destructor to
this:

AccessManager::~AccessManager()
{
QObjectList childList = children();
Q_FOREACH(QObject *child, childList) {
QNetworkReply *reply = qobject_cast<QNetworkReply*>(child);
if (reply != 0) {
qDebug() << "Setting reply parent to null";
reply->setParent(0);
qDebug() << "deleting reply object";
delete reply;
} else {
qDebug() << "child " << child << " isn't a networkreply"
<< "it is a " << child->metaObject()->className();
}
}
delete d;
}

and got this output before the crash:

[Thread 0x7fffd3fff700 (LWP 17285) exited]
[Thread 0x7fffe7128700 (LWP 17279) exited]
child KIO::Integration::CookieJar(0xa2dc50) isn't a networkreply it is a
KIO::Integration::CookieJar

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff720057e in
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>::~QExplicitlySharedDataPointer
(this=0xa14d30, __in_chrg=<optimized out>)
at
../../include/QtCore/../../../../qt5/qtbase/src/corelib/tools/qshareddata.h:156
156 inline ~QExplicitlySharedDataPointer() { if (d &&
!d->ref.deref()) delete d; }

So unless the cookiejar is making QNetworkAccessManager's destructor fail I
don't see how this could be a solution for the problem unfortunately.

thanks,
Jeremy

On Mon, Nov 17, 2014 at 6:50 AM, Thomas Lübking <thomas. ... at gmail dot com>
wrote:

Re: attica_kde.so closing crash

By Jeremy Paul Whiting at 11/16/2014 - 21:09

I'm not deleting anything in the destructor except m_wallet which is a
KWallet. The crash is in the base class destructor QNetworkAccessManager.
I'll try valgrind. good idea.

Re: attica_kde.so closing crash

By Jeremy Paul Whiting at 11/16/2014 - 21:18

Hmm, valgrind shows QNetworkAccessManager is reading some location it
shouldn't inside it's destructor:

==22353== Invalid read of size 8
==22353== at 0x59BE57E:
QExplicitlySharedDataPointer<QNetworkConfigurationPrivate>::~QExplicitlySharedDataPointer()
(in /home/jeremy/devel/kde/src/qt5build/qtbase/lib/libQt5Network.so.5.
4.0)
==22353== by 0x59BD977: QNetworkConfiguration::~QNetworkConfiguration()
(qnetworkconfiguration.cpp:304)
==22353== by 0x597B9E0:
QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate()
(qnetworkaccessmanager.cpp:1488)
==22353== by 0x597BA6B:
QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate()
(qnetworkaccessmanager.cpp:1499)
==22353== by 0x7E20C6F:
QScopedPointerDeleter<QObjectData>::cleanup(QObjectData*)
(qscopedpointer.h:54)
==22353== by 0x7E1F25A: QScopedPointer<QObjectData,
QScopedPointerDeleter<QObjectData> >::~QScopedPointer()
(qscopedpointer.h:101)
==22353== by 0x7E147DA: QObject::~QObject() (qobject.cpp:882)
==22353== by 0x5978E02: QNetworkAccessManager::~QNetworkAccessManager()
(qnetworkaccessmanager.cpp:466)
==22353== by 0x9083BA4: KIO::AccessManager::~AccessManager()
(accessmanager.cpp:121)
==22353== by 0x9083BD3: KIO::AccessManager::~AccessManager()
(accessmanager.cpp:126)
==22353== by 0x7E1614F: QObjectPrivate::deleteChildren()
(qobject.cpp:1950)
==22353== by 0x7E14767: QObject::~QObject() (qobject.cpp:1030)
==22353== Address 0x1cd1b758 is not stack'd, malloc'd or (recently) free'd
==22353==
KCrash: crashing... crashRecursionCounter = 2
KCrash: Application Name = khotnewstuff path =
/home/jeremy/devel/kde/build/frameworks/knewstuff/tests pid = 22353
KCrash: Arguments:
/home/jeremy/devel/kde/build/frameworks/knewstuff/tests/khotnewstuff
parley-themes.knsrc
KCrash: Attempting to start /usr/local/lib/libexec/drkonqi from kdeinit
sock_file=/run/user/1000/kdeinit5__0

[1]+ Stopped valgrind --leak-check=full ./khotnewstuff
parley-themes.knsrc

then valgrind crashes too :/

BTW, this code is two files, a .h and .cpp in
plasma-desktop/attica-kde/kdeplugin/ if anyone wants to see the code. I
don't have any local changes besides adding qDebug() lines.

Re: attica_kde.so closing crash

By Thiago Macieira at 11/17/2014 - 15:02

On Sunday 16 November 2014 18:18:07 Jeremy Whiting wrote:
This looks like the case of accessing memory from a plugin that has been
unloaded.

Note how the backtrace started from qlibraryCleanup in qlibrary.cpp, which is
unloading all plugins.

This is a plugin-unload-order problem. The KDE platform plugin got unloaded
after the bearer manager plugin.

Re: attica_kde.so closing crash

By Jeremy Paul Whiting at 11/17/2014 - 15:07

Ok, how can I fix the unload order then?

Re: attica_kde.so closing crash

By Thiago Macieira at 11/17/2014 - 15:26

On Monday 17 November 2014 12:07:36 Jeremy Whiting wrote:
You don't. The libraries are unloaded in alphabetical order, but I might
change that later to a QHash and then the order is arbitrary and random.

Fix the problem in a different way. If necessary, submit a patch to
QNetworkAccessManager and/or the bearer plugins so it stops tracking the
pointer on plugin unload.

Re: attica_kde.so closing crash

By Albert Astals Cid at 11/16/2014 - 19:25

El Diumenge, 16 de novembre de 2014, a les 13:50:03, Jeremy Whiting va
escriure:
Try running it with valgrind, may tell you something more itneresting.

Cheers,
Albert