Work around an unfixed glibc bug in dlclose(3) on exit
During exit, libraries are unloaded and global destructors are run. If we call dlclose(3) from inside the global destructors, we might be telling libdl to unload a module it has already unloaded. I cannot reproduce the issue on my Fedora 17 machine with glibc 2.15, but it could be reliably be reproduced on an Ubuntu 11.10. The assertion is identical to the one reported upstream at http://sourceware.org/bugzilla/show_bug.cgi?id=11941 (see better explanation at https://bugzilla.novell.com/show_bug.cgi?id=622977). I cannot find any evidence in glibc's source code that the bug has been fixed. Change-Id: I97745f89e8c5481196e645dada8762d607a9fb2c Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
288d3aceee
commit
0da5471664
@ -376,7 +376,14 @@ inline void QLibraryStore::cleanup()
|
||||
Q_ASSERT(lib->pHnd);
|
||||
Q_ASSERT(lib->libraryUnloadCount.load() > 0);
|
||||
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);
|
||||
#else
|
||||
lib->unload();
|
||||
#endif
|
||||
delete lib;
|
||||
it.value() = 0;
|
||||
}
|
||||
@ -490,15 +497,16 @@ bool QLibraryPrivate::load()
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool QLibraryPrivate::unload()
|
||||
bool QLibraryPrivate::unload(UnloadFlag flag)
|
||||
{
|
||||
if (!pHnd)
|
||||
return false;
|
||||
if (!libraryUnloadCount.deref()) { // only unload if ALL QLibrary instance wanted to
|
||||
delete inst.data();
|
||||
if (unload_sys()) {
|
||||
if (flag == NoUnloadSys || unload_sys()) {
|
||||
if (qt_debug_component())
|
||||
qWarning() << "QLibraryPrivate::unload succeeded on" << fileName;
|
||||
qWarning() << "QLibraryPrivate::unload succeeded on" << fileName
|
||||
<< (flag == NoUnloadSys ? "(faked)" : "");
|
||||
//when the library is unloaded, we release the reference on it so that 'this'
|
||||
//can get deleted
|
||||
libraryRefCount.deref();
|
||||
|
@ -83,12 +83,14 @@ public:
|
||||
#endif
|
||||
pHnd;
|
||||
|
||||
enum UnloadFlag { UnloadSys, NoUnloadSys };
|
||||
|
||||
QString fileName, qualifiedFileName;
|
||||
QString fullVersion;
|
||||
|
||||
bool load();
|
||||
bool loadPlugin(); // loads and resolves instance
|
||||
bool unload();
|
||||
bool unload(UnloadFlag flag = UnloadSys);
|
||||
void release();
|
||||
QFunctionPointer resolve(const char *);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user