Hi Phil,

a little crasher:

==============================================
from PyQt4.QtCore import *

app = QCoreApplication([])
for i in range(300):
    print i
    w1 = QObject(None)
    w2 = QObject(None)
    print id(w1), id(w2)
    QObject.connect(w2, SIGNAL("CRASH"), w1, SIGNAL("CRASH"))
    w2.emit(SIGNAL("CRASH"))
==============================================

This snippet segfaults on both Linux and Windows with recent SIP/PyQt versions. The segfault is due to an infinite loop, that can be aborted before it smashes the stack with this patch:

Index: sip/QtCore/qobject.sip
===================================================================
--- sip/QtCore/qobject.sip (revision 13422)
+++ sip/QtCore/qobject.sip (working copy)
@@ -955,9 +955,15 @@
 // wrapped tuple of Python argument objects.
 void PyQtProxy::pysignal(const PyQt_PyObject &pyargs)
 {
+    static int recursion = 0;
+
void *_a[] = {0, const_cast<void *>(reinterpret_cast<const void *>(&pyargs))};

+    recursion += 1;
+    if (recursion == 5)
+       abort();
     QMetaObject::activate(this, &staticMetaObject, 0, _a);
+    recursion -= 1;
 }


I *think* it's related to an instance's address being reused by Python before PyQt has stopped bookkeeping its existence. On my computer, this is the output:

0
9193416 9193488
1
9193560 9193416
2
9193488 9193560
[segfault]

As you can see, the instance address is reused by Python, and this somewhat triggers the infinite loop in dispatching the signal (the signal becomes connected to the same instance emitting it).
--
Giovanni Bajo

_______________________________________________
PyQt mailing list    [email protected]
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Reply via email to