[PyQt] Object lifetime related segfault on linux
Phil Thompson
phil at riverbankcomputing.com
Fri Oct 10 17:24:55 BST 2014
On 09/10/2014 12:28 pm, Kovid Goyal wrote:
> I've recently started getting a seemingly random crash on program
> termination on linux x64. It can be reproduced with this script:
>
> from PyQt5.Qt import QApplication, QMainWindow
>
> app = QApplication([])
>
> w = QMainWindow()
> w.show()
> app.exec_()
>
>
> Running it with python2 causes a segfault about once in 20 executions.
> Unfortunately, there is stack corruption so the backtrace is not very
> useful. And the crash does not occur running under gdb.
>
> #0 0x00007f0ab58d5069 in ?? ()
> #1 0x00007f0ab3bb0f10 in ?? ()
> #2 0x00000000018c8920 in ?? ()
> #3 0x00007f0ab3bb0f50 in ?? ()
> #4 0x00000000018c8c80 in ?? ()
> #5 0x00007f0ab3bb1700 in ?? ()
> #6 0x00007f0acd8b03be in QThreadPrivate::start (arg=0x18c8920) at
> thread/qthread_unix.cpp:345
> Backtrace stopped: previous frame inner to this frame (corrupt stack?)
>
> I can however avoid the crash by adding
>
> del w
> del app
>
> to the end of the script. In other words explicitly deleting the
> QMainWindow before the QApplication prevents the crash. As I understand
> it this should not be necessary as qapplication.sip should be
> transferring ownership of top level widgets to C++ in the QApplication
> destructor, and indeed, sip.ispyowned() indicates that ownership is
> transferred in the QApplication destructor, so there is something else
> going on here. It might just be a timing issue that the explicit
> deletion avoids.
>
> This is with Qt 5.3.2 and PyQt 5.3.2. In the above back trace there is
> a
> reference to the start method of QThreadPrivate. Looking through the Qt
> source code I can find no reason for a thread being started during
> application shutdown. The xcb QPA plugin does start a thread to talk to
> the X server, but that is during startup.
>
> Obviously, for this simple script the fix is to delete the QMainWindow
> before QApplication. However doing that in a more complex application
> is
> not always possible (the best I can think of is to save the main window
> as an
> attribute of the application object). That should ensure that main
> window is either deleted before the application or not at all because
> of
> a reference cycle. But I would like to have a proper fix for this,
> since
> if it is a timing issue then this fix may not be robust.
Have you ever tried running with a version of PyQt built with tracing
enabled? It might provide some additional information.
Phil
More information about the PyQt
mailing list