[Development] RFD: plugins vs QStringLiterals

Hausmann Simon Simon.Hausmann at theqtcompany.com
Thu Nov 5 17:57:49 CET 2015


And moc data is affected in a similar way. I continue to be in favor of (3)

Simon

  Original Message
From: Thiago Macieira
Sent: Friday, November 6, 2015 00:44
To: development at qt-project.org
Subject: [Development] RFD: plugins vs QStringLiterals


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

_______________________________________________
Development mailing list
Development at qt-project.org
http://lists.qt-project.org/mailman/listinfo/development



More information about the Development mailing list