[Development] RFD: plugins vs QStringLiterals

Jędrzej Nowacki jedrzej.nowacki at theqtcompany.com
Fri Nov 6 08:49:04 CET 2015


And every small, movable object kept in QVariant is affected. QMetaType also 
keeps pointers to functions defined in plugins if such register a type. I 
believe that we had that discussion around Qt4->Qt5 migration. Unloading 
plugins is not safe, sometimes it works but still it is very tricky. I agree 
with Simon and I'm in favor of 3.

Cheers,
 Jędrek

On Thursday 05 of November 2015 16:57:49 Hausmann Simon wrote:
> 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
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development




More information about the Development mailing list