[PyQt] Bug report: crash when using QSytemTrayIcon

z zoomer.gm at gmail.com
Mon Mar 15 12:40:14 GMT 2010


2010/3/15 Phil Thompson <phil at riverbankcomputing.com>

> On Mon, 15 Mar 2010 15:12:01 +0300, z <zoomer.gm at gmail.com> wrote:
> > 2010/3/15 Phil Thompson <phil at riverbankcomputing.com>
> >
> >> On Sun, 14 Mar 2010 22:06:02 +0300, z <zoomer.gm at gmail.com> wrote:
> >> > 2010/3/5 Phil Thompson <phil at riverbankcomputing.com>
> >> >
> >> >> On Fri, 5 Mar 2010 00:35:21 +0100, Kiwi <spiky.kiwi at gmail.com>
> wrote:
> >> >> > Hi,
> >> >> > I'm totally new to PyQt programming.
> >> >> > While I was writing a very simple app for the system tray I think I
> >> >> > found
> >> >> a
> >> >> > bug.
> >> >> > Here is a simple testcase:
> >> >> >
> >> >> > # -*- coding: utf-8 -*-
> >> >> > import sys
> >> >> > from PyQt4 import QtGui, QtCore
> >> >> >
> >> >> > app = QtGui.QApplication(sys.argv)
> >> >> >
> >> >> > tray = QtGui.QSystemTrayIcon()
> >> >> >
> >> >> > def a(): pass
> >> >> > def b(): pass
> >> >> > def c(): pass
> >> >> > def d(): pass
> >> >> > def e(): pass
> >> >> > def f(): pass
> >> >> > def g(): pass
> >> >> > def h(): pass
> >> >> > def i(): pass
> >> >> > def j(): pass
> >> >> > def k(): pass
> >> >> >
> >> >> > cm = QtGui.QMenu()
> >> >> > cm.addAction("Exit",QtGui.QApplication.quit)
> >> >> >
> >> >> > tray.setContextMenu(cm)
> >> >> >
> >> >> > tray.show()
> >> >> > sys.exit(app.exec_())
> >> >> >
> >> >> >
> >> >> > note that the "defs" are needed to make the crash happen.
> >> >> > FYI, running linux on x86_64
> >> >> > versions:
> >> >> > qt: 4.6.2
> >> >> > pyqt: 4 4.7
> >> >> > sip: 4.10
> >> >> > python: 2.6.4
> >> >> > gcc: 4.4.3
> >> >> > libX11 1.3.3
> >> >> >
> >> >> > here is the backtrace:
> >> >> > (gdb) run
> >> >> > Starting program: /usr/bin/python2.6 crash.py
> >> >> > [Thread debugging using libthread_db enabled]
> >> >> > QSystemTrayIcon::setVisible: No Icon set
> >> >> >
> >> >> > Program received signal SIGSEGV, Segmentation fault.
> >> >> > XFreeColormap (dpy=0x0, cmap=16777218) at FreeCmap.c:41
> >> >> > 41      FreeCmap.c: No such file or directory.
> >> >> >         in FreeCmap.c
> >> >> > (gdb) bt
> >> >> > #0  XFreeColormap (dpy=0x0, cmap=16777218) at FreeCmap.c:41
> >> >> > #1  0x00007ffff5f1b558 in ~QSystemTrayIconSys (this=0x9c3070,
> >> >> > __in_chrg=<value optimized out>) at
> util/qsystemtrayicon_x11.cpp:213
> >> >> > #2  0x00007ffff5f19ff4 in QSystemTrayIconPrivate::remove_sys
> >> >> > (this=0x9bc310) at util/qsystemtrayicon_x11.cpp:352
> >> >> > #3  0x00007ffff5f0637f in ~QSystemTrayIcon (this=0x8c6590,
> >> >> > __in_chrg=<value optimized out>) at util/qsystemtrayicon.cpp:152
> >> >> > #4  0x00007ffff65f46f2 in ~sipQSystemTrayIcon (this=0x8c6590,
> >> >> > __in_chrg=<value optimized out>) at sipQtGuiQSystemTrayIcon.cpp:137
> >> >> > #5  0x00007ffff65f347c in release_QSystemTrayIcon
> (sipCppV=0x8c6590,
> >> >> > sipState=<value optimized out>) at sipQtGuiQSystemTrayIcon.cpp:752
> >> >> > #6  0x00007ffff219c289 in sipWrapper_dealloc (self=0x0) at
> >> >> > siplib.c:9675
> >> >> > #7  0x00007ffff7adc0e5 in subtype_dealloc (self=0x7ffff7f1caf0) at
> >> >> > Objects/typeobject.c:1019
> >> >> > #8  0x00007ffff7aba0cf in insertdict (mp=0x63cf60,
> >> >> > key=0x7ffff7f08870,
> >> >> > hash=2314047222216391292, value=0x7ffff7dab5d0) at
> >> >> > Objects/dictobject.c:459
> >> >> > #9  0x00007ffff7abcb15 in PyDict_SetItem (op=0x63cf60,
> >> >> > key=0x7ffff7f08870, value=0x7ffff7dab5d0) at
> >> >> > Objects/dictobject.c:701
> >> >> > #10 0x00007ffff7abe48d in _PyModule_Clear (m=<value optimized out>)
> >> >> > at
> >> >> > Objects/moduleobject.c:138
> >> >> > #11 0x00007ffff7b2ac4f in PyImport_Cleanup () at
> Python/import.c:439
> >> >> > #12 0x00007ffff7b33c46 in Py_Finalize () at Python/pythonrun.c:434
> >> >> > #13 0x00007ffff7b33d58 in Py_Exit (sts=0) at
> Python/pythonrun.c:1714
> >> >> > #14 0x00007ffff7b33e87 in handle_system_exit () at
> >> >> Python/pythonrun.c:1116
> >> >> > #15 0x00007ffff7b340cd in PyErr_PrintEx (set_sys_last_vars=1) at
> >> >> > Python/pythonrun.c:1126
> >> >> > #16 0x00007ffff7b345a6 in PyRun_SimpleFileExFlags
> >> >> > (fp=0x7fffffffe578,
> >> >> > filename=0x7fffffffe578 "crash.py", closeit=1,
> flags=0x7fffffffe0d0)
> >> >> > at Python/pythonrun.c:935
> >> >> > #17 0x00007ffff7b40721 in Py_Main (argc=-134926176, argv=<value
> >> >> > optimized out>) at Modules/main.c:599
> >> >> > #18 0x00007ffff74ebbbd in __libc_start_main (main=<value optimized
> >> >> > out>, argc=<value optimized out>, ubp_av=<value optimized out>,
> >> >> > init=<value optimized out>,
> >> >> >     fini=<value optimized out>, rtld_fini=<value optimized out>,
> >> >> > stack_end=0x7fffffffe1e8) at libc-start.c:220
> >> >> > #19 0x00000000004006b
> >> >> > (gdb) f 6
> >> >> > #6  0x00007ffff219c289 in sipWrapper_dealloc (self=0x0) at
> >> >> > siplib.c:9675
> >> >> > 9675        forgetObject((sipSimpleWrapper *)self);
> >> >> > (gdb) f 5
> >> >> > #5  0x00007ffff65f347c in release_QSystemTrayIcon
> (sipCppV=0x8c6590,
> >> >> > sipState=<value optimized out>) at sipQtGuiQSystemTrayIcon.cpp:752
> >> >> > warning: Source file is more recent than executable.
> >> >> > 752             delete reinterpret_cast<QSystemTrayIcon
> *>(sipCppV);
> >> >> > Current language:  auto
> >> >> > The current source language is "auto; currently c++".
> >> >> > (gdb) f 4
> >> >> > #4  0x00007ffff65f46f2 in ~sipQSystemTrayIcon (this=0x8c6590,
> >> >> > __in_chrg=<value optimized out>) at sipQtGuiQSystemTrayIcon.cpp:137
> >> >> > 137     }
> >> >>
> >> >> Crashes on exit like this are caused by Qt objects being deleted in
> >> >> the
> >> >> "wrong" order. Unfortunately PyQt has (almost) no control over that
> >> >> order.
> >> >> By adding those dummy functions you are altering the order in which
> >> >> things
> >> >> get garbage collected. It doesn't happen with C++ applications
> because
> >> >> the
> >> >> objects don't get deleted.
> >> >>
> >> >>
> >> > I found another problem, which i think is also caused by delete order:
> >> > ######
> >> > app = QApplication(sys.argv)
> >> >
> >> > pushButton = QPushButton()
> >> > gProxyButton =  QGraphicsProxyWidget()
> >> > gProxyButton.setWidget(pushButton)
> >> >
> >> > view = QGraphicsView()
> >> > view.show()
> >> >
> >> > app.exec_()
> >> > sys.exit()
> >> > ######
> >> > on exit this program will crash with segfault.
> >> > but if the proxy widget will be added to the scene, or explicitly
> >> > deleted
> >> > afer app.exec_(), all will be fine
> >>
> >> So why would you not add it to a QGraphicsScene?
> >>
> >
> > In my program, i have several items, which will be added to the scene and
> > showed only after some event (button click, for ex.). They are collecting
> > data, while not being shown, and therefore should persist during all
> > application lifetime. But the user might exit application, and do not
> > necessarily trigger their showing action. And application crashes.
>
> Wouldn't it be better to always add the widget to the scene, let Qt create
> the proxy for you, and just hide it until it is needed?
>
Yes, in my usecase it is possible to overcome problem this way. But
requiring an item to be in the scene is a bit strict. Putting such a
restriction on top of Qt is tricky to find out and debug what's happening.
If it can be solved by PyQt itself, the same way as the problem with
QSysremTrayIcon - it would save some blood of developers. (And PySide just
works ;)

>
> Phil
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20100315/49958047/attachment-0001.html>


More information about the PyQt mailing list