[PyQt] Infinite loop in signal bouding of PyQt when using threads.

Alexis Boutillier alexis.boutillier at arteris.com
Thu May 14 13:15:11 BST 2009


Hi,

We came in an infinite loop problem involving threads and PyQt.

Sometimes, our python multi threaded program keep running at 100% of the 
CPU without doing anything nor displaying our widgets.

After backtracing and searching with gdb, we found that the infinite 
loop occurred in the python garbage collector when the second or third 
generation add a pointer to the first generation which is at this moment 
composed of only one element and so keep looping indefinitely on that 
element.

This problem arise because someone create object or change ref count of 
object without locking threads.

After searching the backtrace and PyQt code, we found that the error 
arise when connecting signal and slots.
Precisely, this code (but it should be the same for other connection 
type) is allowed to create object without locking threads.

qpy/QtCore/qpycore_pyqtboundsignal.cpp (line 340):
---
     Py_BEGIN_ALLOW_THREADS

 >>> proxy = new PyQtProxy(bs, slot_obj, &member);
---

Could you please look at it to confirm this is an error or not ?

Here is the backtrace of the infinite loop attached.

#0  PyErr_Occurred () at Python/errors.c:80
#1  0xb7eed5c5 in _PyObject_GC_New (tp=0xb29b1d18) at 
Modules/gcmodule.c:1370
#2  0xb7e8228f in PyWeakref_NewRef (ob=0xb2a8f5ec, callback=0x0) at 
Objects/weakrefobject.c:36
#3  0xb514c311 in getWeakRef (obj=0xb2a8f5ec) at qtlib.c:639
#4  0xb514c16a in sip_api_save_slot (sp=0x876e76c, rxObj=0xb29b1d4c, 
slot=0x0) at qtlib.c:540
#5  0xb69802fd in PyQtProxy::PyQtProxy () from 
/home/ftucky/views/Dev2x/sw/base/purchase/kit/lib/python2.6/site-packages/PyQt4/_qt.so
#6  0xb697effa in pyqtBoundSignal_connect () from 
/home/ftucky/views/Dev2x/sw/base/purchase/kit/lib/python2.6/site-packages/PyQt4/_qt.so
#7  0xb7e5ac51 in PyCFunction_Call (func=0xb2b083ac, arg=0xb71a832c, 
kw=0xb7f58bd0) at Objects/methodobject.c:85
#8  0xb7eb87a5 in PyEval_EvalFrameEx (f=0x870b7a4, throwflag=0) at 
Python/ceval.c:3682
#9  0xb7eb9f3c in PyEval_EvalCodeEx (co=0xb2a998d8, globals=0xb7f58bd0, 
locals=0x0, args=0x870b7a4, argcount=3, kws=0x0, kwcount=0, defs=0x0, 
defcount=0, closure=0x0)
     at Python/ceval.c:2942
#10 0xb7e47274 in function_call (func=0xb2a9e8ec, arg=0xb71a7144, 
kw=0x0) at Objects/funcobject.c:524

Summary:
- Bug is linked to the presence of threads.
- Bug is linked to the frequency of the Python garbage collector calls. 
( i.e. gc.set_threshold() )
- Suspected to induce an infinite loop in the garbage collector.
- Can appear with the former signal/slot policy.

Thanks.
-- 
Boutillier Alexis
Methodology engineer

Arteris SA
The Network-on-Chip Company TM
www.arteris.net

6 par Ariane Immeuble Mercure
78284 Guyancourt Cedex
France
Office: (+33) 1 61 37 38 71
Fax:    (+33) 1 61 37 38 41
Alexis.Boutillier at arteris.net


More information about the PyQt mailing list