[Development] RFD: plugins vs QStringLiterals

Thiago Macieira thiago.macieira at intel.com
Thu Nov 5 17:44:33 CET 2015


Proposal: force QStringLiteral uses to always address a heap-allocated 
QString, instead of pointing to the static data. Possibly, this should be an 
interned atom/quark à la GQuark, so two passes on the same QStringLiteral 
would result in the same heap pointers.

Alternative: force QPluginLoader / QFactoryLoader to fake unloading but not 
really unload. Maybe even QLibrary, if we find people use QLibrary to load Qt-
based plugins instead of our own classes.

Background:

When we created QStringLiteral, we thought it was the best thing since sliced 
bread. We started using it everywhere and so did our users, after our 
recommendations. I even had a session in last years' Dev Days explaining when 
to use QStringLiteral and when not to. The objective of that session was to 
explain performance.

The problem we're seeing is that it's quite easy to violate the precondition 
that the QStringLiteral never, ever disappears. This happens when plugins are 
involved. Any QStringLiteral in a plugin or in a library that gets loaded by 
that plugin is subject to disappearing before the end of the program.

[Henceforth, "plugin" is "any dynamically loaded module, whether intended as a 
library or plugin, including all their dependencies that weren't loaded 
before"]

I've said in the past that unloading plugins is a bad idea in C++. The case 
then was that it's easy to leave objects of a polymorphic class type whose 
virtual table is located in the unloaded plugin. This is not very different, 
since the QStringLiteral's data is also global data not expected to 
disappeaar.

We've already worked around two cases of crash-at-exit caused by this, both 
coincidentally related to QtDBus's interface cache. But this can also happen 
for any other types of cache, like:

	QRegExp rx(QStringLiteral());
	QPixmapCache::insert(QStringLiteral("foo"), px);

What do we do then?

1) Declare it SEP and only apply workarounds for the places where 
QStringLiteral is used in our plugins, suggesting that people do the same in 
their plugins.

Problems: libraries loaded by plugins, fragile.

2) Deep-copy the QStringLiterals
 a) with atom/quark
 b) without

Problem: performance impact, complexity of the atom/quark solution.

3) Never unload any plugins, possibly also compiling our own libraries and 
plugins with -z nodelete. Solves most of the problems, including the C++ 
vtable case.

Problems: doesn't catch bypassing of QLibrary (dlopen/LoadLibrary calls), 
prevents upgrading of plugins without restarting the host application.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Development mailing list