[PyQt] Crash with shortcircuit signals
Giovanni Bajo
rasky at develer.com
Tue Jul 10 17:42:22 BST 2007
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
More information about the PyQt
mailing list