Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-810

Memory corruption & crashes when the garbage collector invoked from a thread cleans up widgets

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2: Important
    • Resolution: Done
    • Affects Version/s: 1.2.2
    • Fix Version/s: 5.12
    • Component/s: PySide, Shiboken
    • Labels:
      None
    • Environment:
      Ubuntu 16.04, qt-4.8.7, pyside 1.2.2
    • Platform/s:
      All
    • Commits:
      6bfbfd6edd0f9701664698768f9ec8d29f96a5bd (pyside-setup/5.12, 15.10.2018, 5.12), bfc7f380a0867044a1642181f2dc002ab88376c9 (pyside-setup/5.12)

      Description

      Using Python threads inside a PySide application causes memory corruption, random crashes, deadlocks, asserts, etc.

      To reproduce (on vanilla Ubuntu 16.04): crash1.py
      Stack trace: [^stack1.txt]

      Both import thread/threading and QThread Python threads are affected.

      This bug means that Python threads cannot be used safely inside a PySide application at all.

      The problem stems from the fact that the Python garbage collector run can be triggered by the Python interpreter on any Python thread and at any point in time.

      The garbage collector calls into SbkDeallocWrapper which in turn calls the QWidget destructor (QWidget::~QWidget) on a secondary thread which causes memory corruption, crashes & deadlocks as QWidget methods must not be called from any secondary threads as per definition.

      If you run a Qt debug build, you'll see the following assert:

      ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 7f5af8001180. Receiver '' (of type 'QWidget') was created in thread 2749e30", file kernel/qcoreapplication.cpp, line 539
      

      See also https://riverbankcomputing.com/pipermail/pyqt/2011-August/030378.html

      Recommended fix: Defer de-allocation of QWidget C++ objects inside SbkDeallocWrapper to the main UI thread (e.g. via deleteLater or via tracking them in an internal list).

      The suggested work-around to disable the Python garbage collector and only manually collect in the main UI thread is neither practical nor performant.

        Attachments

        1. crash1.py
          0.5 kB
        2. pyside810.py
          2 kB
        3. pyside810pyqt.py
          2 kB
        4. pyside810pytqt.py
          0.7 kB

          Issue Links

          For Gerrit Dashboard: PYSIDE-810
          # Subject Branch Project Status CR V

            Activity

              People

              • Assignee:
                kleint Friedemann Kleint
                Reporter:
                teijo Teijo Holzer
              • Votes:
                1 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes