[Development] Quick report on loading Qt 5 and 6 in the same process

Thiago Macieira thiago.macieira at intel.com
Tue May 16 06:23:21 CEST 2023


I've been trying to help someone in Slack[1] with a heisenbug that a Qt-based 
application ended up deadlocking only when run with QProcess. After some 
debugging, we've found out that both Qt5 and Qt6 libraries are loaded in the 
same process. We still don't know why this happened because all our attempts 
to find out why cause the problem to disappear.

Anyway, the debugging so far has shown that the use of ELF visibility has NOT 
sufficed to separate the two library sets sufficiently. There were still symbol 
clashes, causing one library to use functions from the other and thus 
misbehave. Though there's nothing we can do about it and we can't remove the 
feature right now, before Qt 7.

The reason for this is, of all things, inline functions. Because those user 
libraries and applications don't use version scripts of their own, the Qt 
symbols for inline functions that end up in their dynamic symbol tables won't 
have a "Qt5" or "Qt6" version marker. Therefore, they match both.

And there are two reasons why those inline symbols end up in the symbol table:

1) third party code being compiled without -fvisibility-inlines-hidden
We can't enforce that people use this flag in their applications and libraries 
(though they should). This means any inline function that didn't get inlined 
will then be part of the dynamic symbol table of the module in question.

This is the case of the user: libQt5DBus.so.5 made a call to function symbol 
_ZeqRK7QStringS1_  (operator==), which got resolved to the main application, 
which is Qt 6.

2) an apparent GCC bug even with -fvisibility-inlines-hidden
For some reason, some inline functions are not hidden, even with GCC 13[2]. 
Since there's no apparent reason why this should happen, I think it's a GCC 
bug. It doesn't happen with Clang. I've discovered this when trying to 
understand how to mitigate the problem.

There may be a third source, that of inline Q_DECL_EXPORT variables. I don't 
think we have any such in our code today and Qt 5 couldn't use them, so this 
is not a problem right now.

[1] https://cpplang.slack.com/archives/C29936TQC/p1683900238213659
[2] in debug mode uic.cpp.o, all "QStirng::" functions are HIDDEN, except for 
QString::clear().

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Cloud Software Architect - Intel DCAI Cloud Engineering
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5152 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20230515/91252faa/attachment-0001.bin>


More information about the Development mailing list