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

QSerialPort emits error in destructor



    • Type: Suggestion
    • Status: Closed
    • Priority: Not Evaluated
    • Resolution: Done
    • Affects Version/s: 5.2.1, 5.3.0
    • Fix Version/s: 5.3.1
    • Component/s: Serial Port
    • Labels:
    • Commits:


      QSerialPort::~QSerialPort() helpfully calls QSerialPort::close() to ensure the serial port is not in use anymore. close() in turn emits an error [1] if it is called when it's already closed. This results in an error every time a QSerialPort is destroyed which has never been open()'ed or has already been close()'d manually.

      This wouldn't be much of a problem as the object is destroyed anyway, but it does emit a signal in the process. This signal can be inconvenient as it is emitted during a destructor call: If a class Foo has a QSerialPort instance as a member and has a slot connected to the QSerialPort::SerialPortError signal, the slot is called after the Foo's destructor. This can cause some mayhem as Foo is already destroyed.

      See attached code for an example.

      I propose a simple fix for the solution: don't call close() in the destructor if the port is already closed.

      E.g. in [2], instead of


      { close(); delete d_ptr; }

      use this


      { if (this->isOpen()) close(); delete d_ptr; }

      To summarize:

      1. an object Foo derived from QObject and having an instance of QSerialPort is destroyed
      2. Foo::~Foo() is called, Foo gets destroyed
      3. QSerialPort::~QSerialPort() is called and calls QSerialPort::close()
      4. QSerialPort::close() emits an error signal because it is already closed
      5. The problem: This signal may now call Foo::someslot() even tough Foo was already destroyed in step 2
      6. all members of Foo are destroyed, now it's ancestors are destroyed: QObject::~QObject() is called and disconnects all its signals and slots

      Normally, a signal will never call a slot of a destroyed object as QObject::~QObject() will disconnect a destroyed object, but the destructor of a parent class is called after the destructor of the members of the class.

      [1] https://qt.gitorious.org/qt/qtserialport/source/04a3308346190a70509a759423993f6bcc365328:src/serialport/qserialport.cpp#L564-1371

      [2] https://qt.gitorious.org/qt/qtserialport/source/04a3308346190a70509a759423993f6bcc365328:src/serialport/qserialport.cpp#L425-1371


        1. main.cpp
          0.1 kB
          Samuel Bryner
        2. SerialPortCrash.pro
          0.4 kB
          Samuel Bryner
        3. serialthing.cpp
          0.7 kB
          Samuel Bryner
        4. serialthing.h
          0.4 kB
          Samuel Bryner
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.



            iliis Samuel Bryner
            iliis Samuel Bryner
            0 Vote for this issue
            2 Start watching this issue



                Gerrit Reviews

                There are no open Gerrit changes