Details
-
Bug
-
Resolution: Done
-
P3: Somewhat important
-
6.2.4
-
None
-
-
bc6087fce2 (qt/qtbase/dev) bc6087fce2 (qt/tqtc-qtbase/dev) 47bf1a5756 (qt/qtbase/6.2) 47bf1a5756 (qt/tqtc-qtbase/6.2) dd4b0a3ab9 (qt/qtbase/6.3) dd4b0a3ab9 (qt/tqtc-qtbase/6.3)
Description
I've built Qt 6.2.4 for Windows arm64 ('ve attached the configure output). I did try without ltcg and the problem remains.
After linking my application against the release build of Qt, I noticed it crashing during startup, in QObjectPrivate::addConnection. Further inspection found that the root cause was actually this loop in resizeSignalVector:
for (int i = start; i < int(size); ++i) newVector->at(i) = ConnectionList();
The compiler has generated this loop such that space on the stack is reserved for a single ConnectionList object, which is then copied repeatedly to each element in newVector. However, in a release build, the initialization of that stack space is missing, resulting in garbage being placed into the destination objects and a later crash. This is actually quite visible in IDA (red indicates the decompiler thinks the variable may be used before being initialized):
I was able to work around the issue with
for (int i = start; i < int(size); ++i) { auto &x = newVector->at(i); x.first.storeRelaxed(nullptr); x.last.storeRelaxed(nullptr); }
I'm not sure if this is a compiler bug or some subtle issue in Qt's atomic code (or the SignalVector code?). It seems like a compiler bug should result in instances of the issue occurring elsewhere as well, but I at least haven't hit any other crashes, yet.
It may be notable that replacing one of the storeRelaxed() calls in the workaround with "= nullptr" causes the bug to reappear, just for a single pointer.
Something truly weird to me is that the workaround above causes a bug when building the x64 (host) build of Qt. When the workaround is applied, and x64 is built, I get an error saying the following command returned 1:
E:/qsc/6.2.4_dolphin.x64.build/qtbase/bin/uic.exe -o E:/qsc/6.2.4_dolphin.x64.build/qtbase/src/widgets/Widgets_autogen/include_RelWithDebInfo/ui_qfiledialog.h E:/qsc/qt-everywhere-src-6.2.4/qtbase/src/widgets/dialogs/qfiledialog.ui
Re-running this command manually results in return code 0, and the output file looks ok.