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

QThreadStorage leaks memory when qDebug() is used within a stored data class destructor

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • None
    • 4.7.1
    • Core: Threads
    • None
    • uname: Linux-2.6.32.24-generic #42-Ubuntu SMP Fri Aug 20 14:21:58 UTC 2010 x86_64 GNU/Linux
    • ed8f3b6c98f1b305f0d183bc70c5f810a9c45ef2

    Description

      If qDebug()/qWarning() statements are used inside a destructor of a class that's being stored in QThreadStorage, we leak memory.

      A simple test application and a valgrind log attached.

      ==7605== 32,872 (20 direct, 32,852 indirect) bytes in 1 blocks are definitely lost in loss record 52 of 54
      ==7605==    at 0x402569A: operator new(unsigned int) (vg_replace_malloc.c:255)
      ==7605==    by 0x4C62187: QIconvCodec::convertFromUnicode(QChar const*, int, QTextCodec::ConverterState*) const (qiconvcodec.cpp:327)
      ==7605==    by 0x4C5B2E8: QTextCodec::fromUnicode(QString const&) const (qtextcodec.cpp:1195)
      ==7605==    by 0x4B711CD: QString::toLocal8Bit() const (qstring.cpp:3511)
      ==7605==    by 0x4B1E465: qt_message(QtMsgType, char const*, char*) (qglobal.cpp:2287)
      ==7605==    by 0x4B1E6E5: qDebug(char const*, ...) (qglobal.cpp:2338)
      

      As can be seen from the log, qDebug() calls QString::toLocal8Bit(), which in turn results in a call to QIconvCodec::convertFromUnicode(). This will create a new IconvState instance and store it in QThreadStorage.

      The actual problem is in QThreadStorageData::finish() - entries in TLS are traversed in reverse order, for a good reason i guess. Now, if a destructor adds new data at the tail (or first available position) of the TLS vector, the destructor for that new instance is never called.

      Currently the documentation doesn't say anything about the usage of qDebug()/qWarning() in the destructor of a class stored in QThreadStorage. If this is not fixed, then this should be properly documented.

      Note that the leak happens whenever anything to added to QThreadStorage in a data class destructor, the qDebug() use case is just the most common one.

      Attachments

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

        Activity

          People

            goffart Olivier Goffart (closed Nokia identity) (Inactive)
            treinio Topi Reiniö
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes