[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