[PyQt] Bug report: crash when using QSytemTrayIcon

Phil Thompson phil at riverbankcomputing.com
Fri Mar 5 10:10:23 GMT 2010


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.

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.

Phil


More information about the PyQt mailing list