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

Binary compatibility with QProcess::open and QLocalSocket::open's new override in Qt 5.1

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P0: Blocker
    • Resolution: Done
    • Affects Version/s: 5.1.0
    • Fix Version/s: 5.1.1
    • Component/s: Core: I/O, Network: Sockets
    • Labels:
      None
    • Commits:
      674e79416fefe7b5acf2a8c18d3c91d8feddcc18

      Description

      The QProcess::open() and QLocalSocket::open new overrides in Qt 5.1 cause a binary compatibility issue. Overriding virtuals is permitted as long as calling the old method is still permitted. The trick is: QProcess::start() calls open(), which means it calls the old implementation if the class is derived from QProcess and not recompiled.

      Steps to reproduce:
      1) compile an application that has a class deriving from QProcess or QLocalSocket (e.g., Creator) with Qt 5.0
      2) run it with Qt 5.1
      3) cause it to use that class (with Creator, build any project)

      At this point, the application will freeze for 30 seconds.

      Backtrace:

      (gdb) bt
      #0  0x00007f3688f8add9 in pselect () from /usr/lib/libc.so.6
      #1  0x00007f3689bd5c4e in qt_safe_select(int, fd_set*, fd_set*, fd_set*, timespec const*) () from /usr/lib/libQt5Core.so.5
      #2  0x00007f3689b3ad0c in ?? () from /usr/lib/libQt5Core.so.5
      #3  0x00007f3689b3bbec in ?? () from /usr/lib/libQt5Core.so.5
      #4  0x00007f367698980b in ProjectExplorer::AbstractProcessStep::run(QFutureInterface<bool>&) () from /usr/lib/qtcreator/plugins/QtProject/libProjectExplorer.so
      

      The unknown frames in QtCore must be QProcess::waitForStarted and QProcessPrivate::waitForStarted.

      strace shows the program frozen at:

      pselect6(0, [], NULL, NULL, {30, 0}, {NULL, 8}
      

      The trace does not show any pipes being opened, nor were there any warnings printed in the terminal. Since QProcessPrivate::startProcess always creates a pipe, we know it wasn't called. QProcess::open will always print a warning or call QProcessPrivate::startProcess, so we know QProcess::open wasn't called.

      This can be confirmed by examining the vtable for the process or library in question.

      00000000031f448 R_X86_64_64       typeinfo for Utils::QtcProcess
      000000000031f450 R_X86_64_64       Utils::QtcProcess::metaObject() const
      000000000031f458 R_X86_64_64       Utils::QtcProcess::qt_metacast(char const*)
      000000000031f460 R_X86_64_64       Utils::QtcProcess::qt_metacall(QMetaObject::Call, int, void**)
      000000000031f468 R_X86_64_64       Utils::QtcProcess::~QtcProcess()
      000000000031f470 R_X86_64_64       Utils::QtcProcess::~QtcProcess()
      000000000031f478 R_X86_64_64       QObject::event(QEvent*)
      000000000031f480 R_X86_64_64       QObject::eventFilter(QObject*, QEvent*)
      000000000031f488 R_X86_64_64       QObject::timerEvent(QTimerEvent*)
      000000000031f490 R_X86_64_64       QObject::childEvent(QChildEvent*)
      000000000031f498 R_X86_64_64       QObject::customEvent(QEvent*)
      000000000031f4a0 R_X86_64_64       QObject::connectNotify(QMetaMethod const&)
      000000000031f4a8 R_X86_64_64       QObject::disconnectNotify(QMetaMethod const&)
      000000000031f4b0 R_X86_64_64       QProcess::isSequential() const
      000000000031f4b8 R_X86_64_64       QIODevice::open(QFlags<QIODevice::OpenModeFlag>)
      000000000031f4c0 R_X86_64_64       QProcess::close()
      000000000031f4c8 R_X86_64_64       QIODevice::pos() const
      000000000031f4d0 R_X86_64_64       QIODevice::size() const
      000000000031f4d8 R_X86_64_64       QIODevice::seek(long long)
      000000000031f4e0 R_X86_64_64       QProcess::atEnd() const
      000000000031f4e8 R_X86_64_64       QIODevice::reset()
      000000000031f4f0 R_X86_64_64       QProcess::bytesAvailable() const
      000000000031f4f8 R_X86_64_64       QProcess::bytesToWrite() const
      000000000031f500 R_X86_64_64       QProcess::canReadLine() const
      000000000031f508 R_X86_64_64       QProcess::waitForReadyRead(int)
      000000000031f510 R_X86_64_64       QProcess::waitForBytesWritten(int)
      000000000031f518 R_X86_64_64       QProcess::readData(char*, long long)
      000000000031f520 R_X86_64_64       QIODevice::readLineData(char*, long long)
      000000000031f528 R_X86_64_64       QProcess::writeData(char const*, long long)
      000000000031f530 R_X86_64_64       QProcess::setupChildProcess()
      000000000031f540 R_X86_64_64       QProcess::staticMetaObject
      000000000031f548 R_X86_64_RELATIVE  *ABS*+0x00000000000f0140
      000000000031f550 R_X86_64_RELATIVE  *ABS*+0x00000000000f0100
      000000000031f558 R_X86_64_RELATIVE  *ABS*+0x00000000000db3c0
      000000000031f570 R_X86_64_64       vtable for __cxxabiv1::__si_class_type_info+0x0000000000000010
      

      Note the presence of QIODevice::open on line 15.

        Attachments

          Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            Activity

              People

              Assignee:
              thiago Thiago Macieira
              Reporter:
              thiago Thiago Macieira
              Votes:
              3 Vote for this issue
              Watchers:
              7 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes