[Development] RFD: plugins vs QStringLiterals

Sergio Martins sergio.martins at kdab.com
Thu Nov 5 18:02:25 CET 2015

On Thursday, November 05, 2015 11:44:33 AM Thiago Macieira wrote:
> 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.

+1 for SEP
Document the circumstances where QSL might crash so the user can decide for 
himself what he values most.

Customers will usually want stability, so they probably won't use QSL, but for 
many projects, like KDE, it's important to remove all those heap allocations 
and we tolerate a crash now and then. These crashes are very rare, and when 
they happen they are easy to diagnose and fix. Until now I've only seen the 
dbus crash you fixed and the QRegExp crash which I debugged in 15 minutes 

> 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.

That defeats the purpose of QSL no ?

> 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.


Sérgio Martins | sergio.martins at kdab.com | Software Engineer
Klarälvdalens Datakonsult AB, a KDAB Group company
Tel: Sweden (HQ) +46-563-540090, USA +1-866-777-KDAB(5322)
KDAB - The Qt Experts

More information about the Development mailing list