[PyQt] Bug report: crash when using QSytemTrayIcon

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


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.


> > The workaround is to experiment with explicitly deleting objects after
> >> exec_() returns but before sys.exit() is called. In this case "del tray"
> >> seems to avoid the crash.
> >>
> >> That said, PyQt does have a mechanism for making sure certain objects
> get
> >> deleted before the QApplication does - and it seems that QSystemTrayIcon
> >> should also be handled that way. The change will be in tonight's
> >> snapshot.
> >>
> >
> > So can the problem i described also be fixed the same way, as the OP says
> > (i.e. make QGraphicsProxyWidget deleted before QApplication) ?
>
> I don't see how this is a valid use case.
>

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


More information about the PyQt mailing list