[PyQt] Bug report: crash when using QSytemTrayIcon

Phil Thompson phil at riverbankcomputing.com
Mon Mar 15 08:48:56 GMT 2010


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?

> 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


More information about the PyQt mailing list