PySide Bugzilla Closed for New Bugs

PySide is now a Qt Add-on and uses the Qt Project's JIRA Bug Tracker instead of this Bugzilla instance. This Bugzilla is left for reference purposes.

Bug 1145 - QObjects inside python generator functions can cause segfaults
: QObjects inside python generator functions can cause segfaults
Status: UNCONFIRMED
Product: PySide
Classification: Unclassified
Component: QtCore
: 1.0.6
: PC Linux
: P5 major
Assigned To: Hugo Parente Lima
:
:
:
  Show dependency treegraph
 
Reported: 2012-02-20 18:02 EET by tuukka.verho
Modified: 2012-03-08 16:58 EET (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description tuukka.verho 2012-02-20 18:02:58 EET
Using QtNetwork or QtWebKit (or possibly other Qt classes, I haven't tested)
inside a python generator function may cause segmentation faults after
StopIteration is encountered and the execution goes back to the event loop.
According to valgrind output, the crash happens in
QCoreApplication::postEvent().

A minimal example using QtNetwork is below. The expected output is:

StopIteration caught
finish() called

However, most of the time the output is 

StopIteration caught
Segmentation fault

or

StopIteration caught
QMutex::lock: mutex lock failure: Invalid argument
QMutex::lock: mutex unlock failure: Invalid argument
Segmentation fault

or

StopIteration caught
QMutex::lock: mutex lock failure: Invalid argument
python: tpp.c:66: __pthread_tpp_change_priority: Assertion `previous_prio == -1
|| (previous_prio >= __sched_fifo_min_prio && previous_prio <=
__sched_fifo_max_prio)' failed.
Aborted

Valgrind output is shown in the end of the report. To me it looks like Qt
doesn't realize that the object has been deleted and tries to send an event to
it. I didn't find any feasible workaround, so suggestions are welcome.

I'm running Kubuntu Oneiric 64bit.

from PySide.QtCore import QCoreApplication, QTimer, QUrl
from PySide.QtNetwork import QNetworkAccessManager, QNetworkRequest

class Launcher:
    def __init__(self, gen):
        self.generator = gen
        sig = self.generator.next()
        sig.connect(self.slot)

    def slot(self):
        try:
            self.generator.next()
        except StopIteration:
            print 'StopIteration caught'
            QTimer.singleShot(0, self.finish)

    def finish(self):
        print 'finish() called'
        QCoreApplication.instance().quit()

def genFunc(url):
    # Uncommenting this line prevents the segfault
    #global nm

    nm = QNetworkAccessManager()
    reply = nm.get(QNetworkRequest(QUrl(url)))
    yield reply.finished

    # Commenting the next line prevents the segfault
    reply.readAll()


app = QCoreApplication([])
launcher = Launcher(genFunc('http://qt-project.org'))
app.exec_()

Valgrind output:

==28722== Process terminating with default action of signal 11 (SIGSEGV)
==28722==  Access not within mapped region at address 0x40
==28722==    at 0x8165984: QCoreApplication::postEvent(QObject*, QEvent*, int)
(in /usr/lib/x86_64-linux-gnu/libQtCore.so.4.7.4)
==28722==    by 0x9ACE22B: ??? (in
/usr/lib/x86_64-linux-gnu/libQtNetwork.so.4.7.4)
==28722==    by 0x9AB6870: ??? (in
/usr/lib/x86_64-linux-gnu/libQtNetwork.so.4.7.4)
==28722==    by 0x9ACC85C: ??? (in
/usr/lib/x86_64-linux-gnu/libQtNetwork.so.4.7.4)
==28722==    by 0x9ACC8B0: ??? (in
/usr/lib/x86_64-linux-gnu/libQtNetwork.so.4.7.4)
==28722==    by 0x720E175: ??? (in
/usr/lib/python2.7/dist-packages/PySide/QtCore.so)
==28722==    by 0x8161AFB: QCoreApplication::notifyInternal(QObject*, QEvent*)
(in /usr/lib/x86_64-linux-gnu/libQtCore.so.4.7.4)
==28722==    by 0x816551E: QCoreApplicationPrivate::sendPostedEvents(QObject*,
int, QThreadData*) (in /usr/lib/x86_64-linux-gnu/libQtCore.so.4.7.4)
==28722==    by 0x818CA72: ??? (in
/usr/lib/x86_64-linux-gnu/libQtCore.so.4.7.4)
==28722==    by 0x8E04A5C: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3000.0)
==28722==    by 0x8E05257: ??? (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3000.0)
==28722==    by 0x8E05428: g_main_context_iteration (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3000.0)
Comment 1 tuukka.verho 2012-02-20 19:10:48 EET
Actually calling nm.deleteLater() after reply.readAll() seems to prevent the
segfault. No idea why.
Comment 2 Matti Airas 2012-03-08 16:58:03 EET
PySide is now a Qt-addon and uses Qt Project's JIRA tool for tracking bugs.
Please verify that the bug is still valid and re-submit it in the address
below:

https://bugreports.qt-project.org/

Sorry for the inconvenience!