Re: [PyQt] Freezes and crashes with signal autoconnection
Phil Thompson-5 wrote: > >>I had to replace >> ImageLink arguments in signal definition with 'PyQt_PyObject', not sure >>why exactly) > > Neither am I. > Else I would get the following message: > TypeError: type 'classobj' is not supported as a pyqtSignal() type > argument type > which is funny because the documentation seems to imply that any object can be passed as a signal argument. It might have something to do with the metatype mechanism, although this is yet another PyQt part that is totally obscure to me. > The bug is this line in get_param()... > > res = ulist.first() > > ...which returns the first string in the list and *not* a copy of the > first > string in the list. The result is that you are still using it after Qt has > destroyed it. This behaviour is horribly un-Pythonic but allowed (so I > can't change it as doing so might break other people's code). > > Change the line to... > > res = ulist[0] > > ...and it should be Ok. > Ok it looks like it *does* work now. I think it's too bad but ok to keep the weird behavior for backward compatibility, but at least please someone write a note about it in the documentation! This bug was horrendous with no erorr message, no stack trace and a seemingly random occurrence, hence my feeling that it should have be related to multi-threading. I would never have been able to solve it by myself. Anyway everything seems to work fine now. Thanks a lot for your kind support and patience! Chris -- View this message in context: http://old.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p26842898.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Freezes and crashes with signal autoconnection
Hi Phil, thanks for the detailed explanation, although I have to admit I have a bit of a hard time following through.. Anyway... Phil Thompson-5 wrote: > > I've already suggested that you should simplify your ImageLink class so > that it does not derive from QObject. > Okay but there must be something else here, I did just what you suggested http://old.nabble.com/file/p26701730/main.py here (I had to replace ImageLink arguments in signal definition with 'PyQt_PyObject', not sure why exactly) Still I get the same crash, after a few get_param iterations though, which makes me believe it's not a pure GC'ed object issue : >>python main.py > get_param(http://abcdef.net/st/st.php?id=6630&script=1&url=http://g.ftv.com/4/17/377889&p=60, > url) > get_param(http://g.ftv.com/4/17/377889, url) > > [1]3510 segmentation fault (core dumped) python main.py > >>gdb /usr/bin/python core.3510 > Program terminated with signal 11, Segmentation fault. > > #0 0x00247ef9 in qpycore_PyObject_FromQString (qs...@0x9346a5c) at > qpycore_qstring.cpp:49 > 49 if ((obj = PyUnicode_FromUnicode(NULL, qstr.length())) == > NULL) > > (gdb) bt > > #0 0x00247ef9 in qpycore_PyObject_FromQString (qs...@0x9346a5c) at > qpycore_qstring.cpp:49 > #1 0x001964b9 in slot_QString___str__ (sipSelf=0xb747450c) at > sip/QtCore/qstring.sip:449 > #2 0x03644edf in _PyObject_Str (v=0xb747450c) at Objects/object.c:415 > > #3 0x03654c16 in PyString_Format (format=0xb77df320, args=0xb77e306c) at > Objects/stringobject.c:4839 > #4 0x03655e1f in string_mod (v=0x2b2a2928, w=0xb77e306c) at > Objects/stringobject.c:4116 > [blah blah blah] > Thanks, Chris -- View this message in context: http://old.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p26701730.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Freezes and crashes with signal autoconnection
Hi Phill, Hans, thanks a lot for your answers. Hans-Peter Jansen-2 wrote: > > This does NOT qualify as a small piece of code, because: > - it's convoluted code (e.g. it's not obvious, which part runs threaded) > - you're doing hard to track things with QUrls (this is, where it > crashes) > Well let's say it was the smallest sample I was able to come up with, taking into account the fact that I still do not clearly understand what's wrong with the code and why or where precisely it crashes. So I'm basically going blind here. Hans-Peter Jansen-2 wrote: > > Your clue stick is called gdb [...] eh voilĂ , your code crashes in the > QUrl ctor. Easy, isn't it. This procedure > should help you to isolate your issue. > Yes I was able to get similar results doing it slightly differently, I would remove limits on coredumpsize in shell > ulimit -c unlimited then obtain a core.xyz corefile during the crash and debug it using > gdb /usr/bin/python core.xyz which would give me the same backtrace. However as Phil noted earlier it's still difficult to see what's wrong here. In particular, all the print statements I could add to my code to debug QUrl manipulation would always indicate perfectly well-formed QUrl objects. There's something else going wrong here, that has to do with the asynchronous garbage collection of Python and C++ objects from what I understand, but here halts my insight. Hans-Peter Jansen-2 wrote: > > Doing silly things in Qt results in this behavior, and PyQt cannot not > protect > you here, while it adds some obstacles inherited from Python semantics > (e.g. > lifetime issues). > Ok but what exaclty am I doing wrong ? From my point of view the intent is clear: I manage some lists (QListView) of ImageLink that I want populated by worker threads (QThread). So I launch QThreads that create and set up ImageLink objects locally and then pass them over when ready to the main thread using PyQt signals. All this seems reasonnable at first sight and the documentation doesn't warn against doing that kind of things as much as I can tell. The first problem I encountered was due to the fact that the ImageLink instance passed in the signal does not "contain" a reference to the original ImageLink python object, so the latter could be GC'ed if the sending thread ended before the signal was delivered. Hence the need to use the Qt.BlockingQueuedConnection mode in this particular case, which solves the problem. However now I have another problem. Following Phill latest advice, I read the following part of the documentation: > In the current version QVariant.userType() will correctly return > QMetaType.QObjectStar (or QMetaType.QWidgetStar) but an extra reference to > the Python object is not kept. To avoid a potential crash you should > ensure that you keep a separate reference to the Python object, either > explicitly or implicitly by giving it a parent. > Unfortunaltely these sentences are totally unclear to me. When is QVariant.userType() used? Who does or does not keep a reference to the Python object, and when? In which situation would a crash potentially occur? Worse, eventhough I don't understand the "why", I tried to implement the "how", i.e., naively added the following lines to my code, hoping to have given my poor lonesome QObject some parent by doing so, and not any ordinary parent, the parent of all parents, the very QApplication itself: > class ImageLink(QObject): > > def __init__(self, base, url, href): > QObject.__init__(self) > app = QApplication.instance() > self.moveToThread(app.thread()) > self.setParent(app) > blah blah > Alas, poor Yorich, all this no no avail. Still it crashes faster than the lightning, and grieves my sore heart and my tired soul. Hans-Peter Jansen-2 wrote: > > OTOH, it's a small price to pay for using the most efficient > and versatile toolkit out there with Python. > Well far form me the idea of belitteling the quality of the Qt and/or PyQt frameworks, I'm not an experienced programmer in general and definitely not in the domain of GUIs. However I feel that eventhough the concept is probably beautiful, the code is still evolving fast (read: still not mature) and most of all the documentation is quite succint. In any case I still do not understand the damn issue, so as always... any help greatly appreciated ! :-) Chris -- View this message in context: http://old.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p26686774.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Freezes and crashes with signal autoconnection
Phil Thompson-5 wrote: > > Either way people need a small, self-contained example that demonstrates > the problem. > Hi Phil, I think I've been able to isolate a small piece of code that consistently reproduces the problem. http://old.nabble.com/file/p26619445/main.py This piece of code displays a gray rectangle on my system and systematically crashes when I click on it. My config is as follows: qt-4.5.3-9.fc11.i586.rpm PyQt4-4.5.4-1.fc11.i586.rpm sip-4.8.2-1.fc11.i586.rpm I'd be very interested in understanding what's wrong here because i've been strugling for weeks with incomprehensible crashes that seem to come out of nowhere and I've not the single clue what's going on. Thanks for your support, Chris -- View this message in context: http://old.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p26619445.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Freezes and crashes with signal autoconnection
Hi there, so what should I do about this issue? Should I file a bug report? Or is it only me? The PyQt4 version I'm using is fairly recent however it crashes A LOT! What gives? Thanks for your help, Chris -- View this message in context: http://old.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p26522132.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Freezes and crashes with signal autoconnection
Hi Phil, Phil Thompson-5 wrote: > > I thought you were using current snapshots (where the code that was > crashing was only compiled in with old versions of Qt). > I've just tried against the latest snapshots (sip-4.9.2-snapshot-20091115.tar.gz and PyQt-x11-gpl-4.6.2-snapshot-20091115.tar.gz) however the results are even worse; the application crashes very quickly with the following trace. I suspect it might be related to the installation, however the demos seem to work ok. - Program terminated with signal 11, Segmentation fault. #0 memcpy () at ../sysdeps/i386/i686/memcpy.S:75 in ../sysdeps/i386/i686/memcpy.S Missing separate debuginfos, use: debuginfo-install OpenEXR-libs-1.6.1-8.fc11.i586 e2fsprogs-libs-1.41.4-12.fc11.i586 fontconfig-2.7.1-1.fc11.i586 freetype-2.3.9-5.fc11.i586 ilmbase-1.0.1-4.fc11.i586 jasper-libs-1.900.1-13.fc11.i586 kdelibs-4.3.2-4.fc11.i586 keyutils-libs-1.2-5.fc11.i586 krb5-libs-1.6.3-20.fc11.i586 lcms-libs-1.18-2.fc11.i586 libICE-1.0.4-7.fc11.i586 libSM-1.1.0-4.fc11.i586 libXau-1.0.4-5.fc11.i586 libXcursor-1.1.9-4.fc11.i586 libXdamage-1.1.1-6.fc11.i586 libXfixes-4.0.3-5.fc11.i586 libXi-1.2.1-1.fc11.i586 libXinerama-1.0.3-4.fc11.i586 libXrandr-1.2.99.4-3.fc11.i586 libXrender-0.9.4-5.fc11.i586 libXxf86vm-1.0.2-2.fc11.i586 libattr-2.4.43-3.fc11.i586 libcap-2.16-4.fc11.1.i586 libdrm-2.4.11-2.fc11.i586 libgcrypt-1.4.4-6.fc11.i586 libgpg-error-1.6-3.i586 libjpeg-6b-45.fc11.i586 libmng-1.0.10-2.fc11.i586 libpng-1.2.37-1.fc11.i586 libselinux-2.0.80-1.fc11.i586 libtiff-3.8.2-14.fc11.i586 libxcb-1.2-4.fc11.i586 linuxwacom-0.8.2.2-11.fc11.i586 phonon-4.3.1-102.fc11.i586 qt-x11-4.5.3-9.fc11.i586 xz-libs-4.999.9-0.1.beta.20091007git.fc11.i586 (gdb) bt #0 memcpy () at ../sysdeps/i386/i686/memcpy.S:75 #1 0xb66020d8 in ?? () #2 0x01a0b7a7 in QString::append (this=0xb6621000, s...@0x9ee9490) at /usr/include/bits/string3.h:52 #3 0x04506e8d in QString::operator+= (s=, this=) at ../../src/corelib/tools/qstring.h:269 #4 QTextCursor::insertText (s=, this=) at text/qtextcursor.cpp:1307 #5 0x04507312 in QTextCursor::insertText (this=0xbfeac73c, te...@0xb66020d8) at text/qtextcursor.cpp:1275 #6 0x04499c71 in QTextControlPrivate::append (this=0x9d4ead0, te...@0xb66020d8, format=Qt::AutoText) at text/qtextcontrol.cpp:2740 #7 0x04499dd3 in QTextControl::append (this=0x9d4eac0, te...@0xb66020d8) at text/qtextcontrol.cpp:2754 #8 0x04702459 in QTextEdit::append (this=0x9d4d4f0, te...@0xb66020d8) at widgets/qtextedit.cpp:2597 #9 0x011e3149 in meth_QTextEdit_append (sipSelf=0x9bdd3ac, sipArgs=0x9bdebcc) at sipQtGuiQTextEdit.cpp:3381 #10 0x03641762 in PyCFunction_Call (func=0x9be5fcc, arg=0x9bdebcc, kw=0x0) at Objects/methodobject.c:81 #11 0x0369d5be in call_function (oparg=, pp_stack=) at Python/ceval.c:3679 #12 PyEval_EvalFrameEx (oparg=, pp_stack=) at Python/ceval.c:2370 #13 0x0369ed79 in PyEval_EvalCodeEx (co=0xb781aad0, globals=0xb786e02c, locals=0x0, args=0x9b7d078, argcount=2, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2942 #14 0x0362db87 in function_call (func=0x9be2294, arg=0x9b7d06c, kw=0x0) at Objects/funcobject.c:524 #15 0x0360172c in PyObject_Call (func=0x9be2294, arg=0x9b7d06c, kw=0x0) at Objects/abstract.c:2487 #16 0x03617284 in instancemethod_call (func=0xb73b189c, arg=0x9b7d06c, kw=0x0) at Objects/classobject.c:2579 #17 0x0360172c in PyObject_Call (func=0xb73b189c, arg=0x9bdeb4c, kw=0x0) at Objects/abstract.c:2487 #18 0x03697f14 in PyEval_CallObjectWithKeywords (func=0xb73b189c, arg=0x9bdeb4c, kw=0x0) at Python/ceval.c:3548 #19 0x003ba2ff in ?? () from /usr/lib/python2.6/site-packages/sip.so #20 0xb73b189c in ?? () #21 0x09bdeb4c in ?? () #22 0x in ?? () Current language: auto; currently asm - -- View this message in context: http://old.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p2667.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Freezes and crashes with signal autoconnection
Hi Phil, Phil Thompson-5 wrote: > > It's difficult to see how this would crash if everything else (ie. Python > and Qt) is working as it should. > > However it does imply you are using a very old version of Qt (v4.1). > what leads you to think to an old version is used ? In fact this should really not be the case, here are the packages installed on my system: qt-4.5.3-9.fc11.i586 PyQt4-4.5.4-1.fc11.i586 sip-4.8.2-1.fc11.i586 PyKDE4-4.3.2-1.fc11.i586 It could be that python were using an old pyqt version laying around but I doubt it. Here is the list of libraries I have on my system: >ls -1 /usr/lib/libQt* /usr/lib/libQt3Support_debug.so /usr/lib/libQt3Support.prl /usr/lib/libQt3Support.so /usr/lib/libQt3Support.so.4 /usr/lib/libQt3Support.so.4.5 /usr/lib/libQt3Support.so.4.5.3 /usr/lib/libQtAssistantClient_debug.so /usr/lib/libQtAssistantClient.prl /usr/lib/libQtAssistantClient.so /usr/lib/libQtAssistantClient.so.4 /usr/lib/libQtAssistantClient.so.4.5 /usr/lib/libQtAssistantClient.so.4.5.3 /usr/lib/libQtCLucene_debug.so /usr/lib/libQtCLucene.prl /usr/lib/libQtCLucene.so /usr/lib/libQtCLucene.so.4 /usr/lib/libQtCLucene.so.4.5 /usr/lib/libQtCLucene.so.4.5.3 /usr/lib/libQtCore_debug.so /usr/lib/libQtCore.prl /usr/lib/libQtCore.so /usr/lib/libQtCore.so.4 /usr/lib/libQtCore.so.4.5 /usr/lib/libQtCore.so.4.5.3 /usr/lib/libQtDBus_debug.so /usr/lib/libQtDBus.prl /usr/lib/libQtDBus.so /usr/lib/libQtDBus.so.4 /usr/lib/libQtDBus.so.4.5 /usr/lib/libQtDBus.so.4.5.3 /usr/lib/libQtDesignerComponents_debug.so /usr/lib/libQtDesignerComponents.prl /usr/lib/libQtDesignerComponents.so /usr/lib/libQtDesignerComponents.so.4 /usr/lib/libQtDesignerComponents.so.4.5 /usr/lib/libQtDesignerComponents.so.4.5.3 /usr/lib/libQtDesigner_debug.so /usr/lib/libQtDesigner.prl /usr/lib/libQtDesigner.so /usr/lib/libQtDesigner.so.4 /usr/lib/libQtDesigner.so.4.5 /usr/lib/libQtDesigner.so.4.5.3 /usr/lib/libQtGui_debug.so /usr/lib/libQtGui.prl /usr/lib/libQtGui.so /usr/lib/libQtGui.so.4 /usr/lib/libQtGui.so.4.5 /usr/lib/libQtGui.so.4.5.3 /usr/lib/libQtHelp_debug.so /usr/lib/libQtHelp.prl /usr/lib/libQtHelp.so /usr/lib/libQtHelp.so.4 /usr/lib/libQtHelp.so.4.5 /usr/lib/libQtHelp.so.4.5.3 /usr/lib/libQtNetwork_debug.so /usr/lib/libQtNetwork.prl /usr/lib/libQtNetwork.so /usr/lib/libQtNetwork.so.4 /usr/lib/libQtNetwork.so.4.5 /usr/lib/libQtNetwork.so.4.5.3 /usr/lib/libQtOpenGL_debug.so /usr/lib/libQtOpenGL.prl /usr/lib/libQtOpenGL.so /usr/lib/libQtOpenGL.so.4 /usr/lib/libQtOpenGL.so.4.5 /usr/lib/libQtOpenGL.so.4.5.3 /usr/lib/libQtScript_debug.so /usr/lib/libQtScript.prl /usr/lib/libQtScript.so /usr/lib/libQtScript.so.4 /usr/lib/libQtScript.so.4.5 /usr/lib/libQtScript.so.4.5.3 /usr/lib/libQtScriptTools_debug.so /usr/lib/libQtScriptTools.prl /usr/lib/libQtScriptTools.so /usr/lib/libQtScriptTools.so.4 /usr/lib/libQtScriptTools.so.4.5 /usr/lib/libQtScriptTools.so.4.5.3 /usr/lib/libQtSql_debug.so /usr/lib/libQtSql.prl /usr/lib/libQtSql.so /usr/lib/libQtSql.so.4 /usr/lib/libQtSql.so.4.5 /usr/lib/libQtSql.so.4.5.3 /usr/lib/libQtSvg_debug.so /usr/lib/libQtSvg.prl /usr/lib/libQtSvg.so /usr/lib/libQtSvg.so.4 /usr/lib/libQtSvg.so.4.5 /usr/lib/libQtSvg.so.4.5.3 /usr/lib/libQtTest_debug.so /usr/lib/libQtTest.prl /usr/lib/libQtTest.so /usr/lib/libQtTest.so.4 /usr/lib/libQtTest.so.4.5 /usr/lib/libQtTest.so.4.5.3 /usr/lib/libQtUiTools.a /usr/lib/libQtUiTools_debug.a /usr/lib/libQtUiTools.prl /usr/lib/libQtWebKit_debug.so /usr/lib/libQtWebKit.prl /usr/lib/libQtWebKit.so /usr/lib/libQtWebKit.so.4 /usr/lib/libQtWebKit.so.4.5 /usr/lib/libQtWebKit.so.4.5.3 /usr/lib/libQtXml_debug.so /usr/lib/libQtXmlPatterns_debug.so /usr/lib/libQtXmlPatterns.prl /usr/lib/libQtXmlPatterns.so /usr/lib/libQtXmlPatterns.so.4 /usr/lib/libQtXmlPatterns.so.4.5 /usr/lib/libQtXmlPatterns.so.4.5.3 /usr/lib/libQtXml.prl /usr/lib/
Re: [PyQt] Freezes and crashes with signal autoconnection
Hi again; Phil Thompson-5 wrote: > > I can't remember if you are using snapshots or not, but there are some > issues fixed related to looking up Python reimplementations of virtual > methods. > forget about Windows. The whole thing crashes so quick on Windows XP that I can't even get a glimpse of the main window. I'm using the latest build (PyQt-Py2.6-gpl-4.6.1-1.exe) but not snapshots as I can't compile there. I'd be willing to compile a build there and also get debugger feedback but I would need a pointer on some resource on how to do that on Windows. Back on Linux I also get crashes although much less frequently. The difference is that I'm able to get some feedback from the system in that case so it might prove a bit more useful! Here is the backtrace of a random crash that appears to occur when a thread calls the QUrl.resolved() method. This is with PyQt4-4.5.4-1 and sip-4.8.2. - Program terminated with signal 11, Segmentation fault. #0 0x082c0f23 in qpycore_PyObject_FromQString (qs...@0xb5bd21b8) at qpycore_qstring.cpp:55 55 *pyu++ = (qstr.at(i)).unicode(); (gdb) bt #0 0x082c0f23 in qpycore_PyObject_FromQString (qs...@0xb5bd21b8) at qpycore_qstring.cpp:55 #1 0x0820f4b9 in slot_QString___str__ (sipSelf=0xb2f21f2c) at sip/QtCore/qstring.sip:449 #2 0x03644e04 in PyObject_Unicode (v=0xb2f21f2c) at Objects/object.c:522 #3 0x036791eb in PyUnicodeUCS4_Format (format=0x901dda0, args=0xb2f21f2c) at Objects/unicodeobject.c:8649 #4 0x03655a92 in PyString_Format (format=0x901dda0, args=0xb2f21f2c) at Objects/stringobject.c:5090 #5 0x03655e1f in string_mod (v=0x901dc68, w=0xb2f21f2c) at Objects/stringobject.c:4116 #6 0x03602d03 in binary_op1 (v=0xb7487b20, w=0xb2f21f2c, op_slot=16) at Objects/abstract.c:914 #7 0x0360382b in binary_op (v=0xb7487b20, w=0x0, op_slot=16, op_name=0x36e02c2 "%") at Objects/abstract.c:966 #8 0x03699afe in PyEval_EvalFrameEx (f=0xb5bd2364, throwflag=0) at Python/ceval.c:1152 #9 0x0369df0d in fast_function (nk=, na=, n=, pp_stack=, func=) at Python/ceval.c:3765 #10 call_function (nk=, na=, n=, pp_stack=, func=) at Python/ceval.c:3700 #11 PyEval_EvalFrameEx (nk=, na=, n=, pp_stack=, func=) at Python/ceval.c:2370 #12 0x0369ed79 in PyEval_EvalCodeEx (co=0x8e2eec0, globals=0x8ec52d4, locals=0x0, args=0x91b6e78, argcount=1, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2942 #13 0x0362db87 in function_call (func=0x912ffb4, arg=0x91b6e6c, kw=0x0) at Objects/funcobject.c:524 #14 0x0360172c in PyObject_Call (func=0x912ffb4, arg=0x91b6e6c, kw=0x0) at Objects/abstract.c:2487 #15 0x03617284 in instancemethod_call (func=0xb6783af4, arg=0x91b6e6c, kw=0x0) at Objects/classobject.c:2579 #16 0x0360172c in PyObject_Call (func=0xb6783af4, arg=0xb784f02c, kw=0x0) at Objects/abstract.c:2487 #17 0x03697f14 in PyEval_CallObjectWithKeywords (func=0xb6783af4, arg=0xb784f02c, kw=0x0) at Python/ceval.c:3548 #18 0x00603963 in PyDict_New () at Objects/dictobject.c:224 #19 0x081c7860 in sipVH_QtCore_5 (sipGILState=PyGILState_LOCKED, sipMethod=0xb6783af4) at sipQtCorecmodule.cpp:3763 #20 0x081f233c in sipQThread::run (this=0x9503a28) at sipQtCoreQThread.cpp:215 #21 0x001af2c2 in QThreadPrivate::start (arg=0x9503a28) at thread/qthread_unix.cpp:188 #22 0x00984935 in start_thread (arg=0xb1afdb70) at pthread_create.c:297 #23 0x008b994e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130 --- Chris -- View this message in context: http://old.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p26349989.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Freezes and crashes with signal autoconnection
Hi again! Phil Thompson-5 wrote: > > If you have a list of the QThread instances you can scan the list when > finished() is received to see which one it is. There is an obvious race > condition with that approach. > I don't know if this race condition is obvious but I'm personally unable to identify it. Could you please kindly elaborate a bit for a multi-threading newbie ? :-) Phil Thompson-5 wrote: > > You could define a method in your QThread sub-class that finished() is > connect to. That method just emits another signal but with the QThread > instance as an argument. > I also have a hard time understanding this one. How could finished() connect to a method in the originating thread, which by definition is supposed not to exist anymore since it has emitted this very signal? Or is the semantics for this signal more complex? By the way, I applied the first approach you suggested, i.e., I use Qt.BlockingQueuedConnection when passing arguments in signals from threads to main, and I now have a slot that collects finished() signals, browse the list of threads and deletes those that it finds effectively finished. The behavior is definitely better on Linux, although not perfect, however on Windows I still get lots of crashes with no error messages at all. Sometimes, but not always, the application spurts some weird error messages in the middle of the run, not right before the crash, like > NotImplementedError: QAbstractListModel.rowCount() is abstract and must be > overridden > although this method is overriden of course, and works most of the time; or (the application is using shelve): > Traceback (most recent call last): > File "E:\Python\gallery\gallery\gallery.py", line 107, in data > return QVariant(self.getLink(index).getPixmap()) > File "E:\Python\gallery\gallery\threads.py", line 76, in getPixmap > filepath = imageCache.getImageFile(self) > File "E:\Python\gallery\gallery\threads.py", line 148, in getImageFile > if self.cache.has_key(url): > File "E:\Programs\Python\lib\shelve.py", line 107, in has_key > return key in self.dict > File "E:\Programs\Python\lib\_abcoll.py", line 329, in __contains__ > self[key] > File "E:\Programs\Python\lib\bsddb\__init__.py", line 266, in > __getitem__ > self._checkOpen() > AttributeError: 'str' object has no attribute '_checkOpen' > or simply (this one arrives right before the crash): > NotImplementedError > It all seems to be related to the ImageLink instances emitting a signal towards a QAbstractListModel layoutChanged signal once download is complete. I have no problem when I remove this signal (except of course that the display does not refresh >-() However this all happens in the main thread as far as I can tell. I'm going to try and extract a use case for that one but I'm afraid it won't be easy. In the meantime if you could point me to a possible likely cause I'd be very grateful! Thanks again for your help! Chris -- View this message in context: http://www.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p25932041.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Freezes and crashes with signal autoconnection
Phil Thompson-5 wrote: > > > I think this is all one problem and is nothing to do with threads. There > is > a (necessary) change of behaviour (documented in the current snapshot) > when > wrapping a Python sub-class of a QObject in a QVariant. > > Previously this was first wrapped in a PyQt_PyObject which managed the > reference counts for you so that you didn't need to maintain an explicit > reference to the QObject sub-class (the ImageLink instance in your case). > The problem with that is that nothing outside of PyQt knows what a > PyQt_PyObject is. So C++ code that has a slot or a dynamic property > expecting a QObject*. > > The current behaviour means that you can pass your ImageLink instance > around to code that doesn't know anything about Python - but it means it > won't manage the reference count for you. In your example your ImageLink > instance is being garbage collected too soon. Using a blocking connection > serialises access to it making sure that it is used before being garbage > collected. Using PyQt_PyObject as the signal signature has the effect of > enforcing the previous behaviour. Hence no crash in either case. > > Phil > Hi Phil, thanks a lot for the explanation, it all makes sense. However I've not been able to fully test it because I bumped into another issue: so now thanks to using Qt.BlockingQueuedConnection, my QThread instances send a signal and wait when they have finished, so the destination slot has time to process the ImageLink parameter. But I cannot keep track of the active threads in this slot anymore. Previously I would do thread = QThread(link) threadList[link] = thread when creating a new QThread and threadList[link].wait() del threadList[link] in the termination slot, in order to keep the necessary references to the existing threads. But now since my threads are blocked, I cannot "forget" them in this slot. So I tried to create a new slot onto which I would connect the finished() signal; at that time I'm sure that the thread is gone, but how can I identify which one? There's no parameter to the signal, and trying to get a reference to the emiting thread by using self.sender() doesn't work either, I guess because precisely the thread is gone for good at that point. So how am I supposed to keep track of those running threads in this situation ? Or am i totally off ? Thanks a lot for your help! Chris -- View this message in context: http://www.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p25884077.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Freezes and crashes with signal autoconnection
Phil Thompson-5 wrote: > > Can you try with the latest installer (though it does contain a nasty > thread-related regression). > > Do you have a test case? > > Phil > Hi Phil, I'm currently using PyQt 4.6-1 with Python 2.6.3. I think I've been able to isolate a http://www.nabble.com/file/p25847873/main.py test case that crashes consistently and demonstrates at least one of the problems I've been experiencing with PyQt multithreading. In this piece of code, when the time delay in the GalleryCreator thread is greater than the delay in the GalleryModel appendLink slot, the application works fine. However if this delay is set to a value less than the latter, then it crashes after a few iterations. It seems that the QAbstractListModel object doesn't like it when a queue of pending events is forming, with custom data types. Also in the second case, the application won't crash if you use Qt.BlockingQueuedConnection instead of AutoConnection (see line 111). This makes sense since in that case no event queue is forming, the Model object has enough time to consume the incoming event before a new one is posted. The application won't crash either if you use 'PyQt_PyObject' instead of ImageLink in the signal argument (see line 88). Don't ask me why :-) Note: I see a similar behaviour on Linux. Chris -- View this message in context: http://www.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p25847873.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Freezes and crashes with signal autoconnection
Hi there, I'm having some problems with a fairly simple multi-threaded application under PyQt 4.5.4 and Windows XP. I have a number of worker threads that feed one consumer in the main GUI thread. Initially I had the worker threads directly call the "add" method of the consumer object; this piece of code was protected by a mutex. So in short: class Worker(QThread): def run(self): ... cache.add(link) class Cache(): def add(self, link): mutex.lock() # Add link to queue mutex.unlock() cache = Cache() This works pretty well but still I'm not completely satisfied. It's bad to execute code that doesn't belong to your thread, right? So I tried to replace that with a signal/slot mechanism: class Worker(QThread): addLink = pyqtSignal(Link) def init(self): self.addLink.connect(cache.add) def run(self): ... link = Link(blah blah) self.addLink.emit(link) class Cache(QObject): def add(self, link): # Add link to queue # No more mutex since access is now serial, right ? ... However the application freezes after a while. No more GUI activity, window not even repainting anymore and Windows tells me "this application is not responding etc" when trying to close. This doesn't happen if I use Qt.DirectConnection or Qt.BlockingQueuedConnection it seems, although I have no idea why. I also notice that with Qt.AutoConnection, the application crashes with no error message unless I use 'PyQt_PyObject' types, with the quotes, in all signal definitions (instead of Link for instance); I don't have this problem either when using Qt.DirectConnection or Qt.BlockingQueuedConnection. So does anyone understand what's going on here under the hood? Is the signal/slot approach the correct way to garantee serial access to a shared resource between threads (the link queue in this example)? Why is this whole thing crashing and freezing like that? Thanks for sharing your insight! Chris -- View this message in context: http://www.nabble.com/Freezes-and-crashes-with-signal-autoconnection-tp25716493p25716493.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt