Fix crash-on-exit with some plugin systems (e.g. sensors)

Don't assume that all entries in the QLibrary global data refer to
libraries have have been loaded. There are three (not two) ways of
getting entries there:

 1) creating a QLibrary
 2) using the static QLibrary::resolve
 3) via plugins

The unload code was meant to handle the first two cases only: libraries
are still loaded at the end of the execution if the static methods were
called or if QLibrary objects were leaked. It didn't handle the case of
plugins being found by the directory scanner in QFactoryLoader but never
loaded.

Note it's possible that this assertion also happened with leaked
QLibrary.

Change-Id: Idcd7a551f96d8fe500cbca682f8014f5122b7584
Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
bb10
Thiago Macieira 2013-02-05 13:39:54 -08:00 committed by The Qt Project
parent 155a20628b
commit f79cc2d66b
1 changed files with 9 additions and 8 deletions

View File

@ -373,17 +373,18 @@ inline void QLibraryStore::cleanup()
for (; it != data->libraryMap.end(); ++it) {
QLibraryPrivate *lib = it.value();
if (lib->libraryRefCount.load() == 1) {
Q_ASSERT(lib->pHnd);
Q_ASSERT(lib->libraryUnloadCount.load() > 0);
lib->libraryUnloadCount.store(1);
if (lib->libraryUnloadCount.load() > 0) {
Q_ASSERT(lib->pHnd);
lib->libraryUnloadCount.store(1);
#ifdef __GLIBC__
// glibc has a bug in unloading from global destructors
// see https://bugzilla.novell.com/show_bug.cgi?id=622977
// and http://sourceware.org/bugzilla/show_bug.cgi?id=11941
lib->unload(QLibraryPrivate::NoUnloadSys);
// glibc has a bug in unloading from global destructors
// see https://bugzilla.novell.com/show_bug.cgi?id=622977
// and http://sourceware.org/bugzilla/show_bug.cgi?id=11941
lib->unload(QLibraryPrivate::NoUnloadSys);
#else
lib->unload();
lib->unload();
#endif
}
delete lib;
it.value() = 0;
}