Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-102246

windows arm64 broken QAtomicPointer ctor/copy/move

    XMLWordPrintable

Details

    • Windows
    • 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.

      Attachments

        1. atomicptr_bug.txt
          20 kB
          shuffle2
        2. atomicptr.cpp
          5 kB
          shuffle2
        3. atomicptr.txt
          4 kB
          shuffle2
        4. disasm-1.txt
          7 kB
          shuffle2
        5. image-2022-04-02-12-32-44-470.png
          14 kB
          shuffle2
        For Gerrit Dashboard: QTBUG-102246
        # Subject Branch Project Status CR V

        Activity

          People

            thiago Thiago Macieira
            shuffle2 shuffle2
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes