<div dir="ltr">Thanks for the feedback. The first two crashes (quickCrash and slowCrash) were, as you say, fairly obvious programmer errors. It would be nice if this would emit some sort of error ("QApplication destroyed; terminating application") with a backtrace.<div><br></div><div>The third case is more interesting -- the cause is more subtle and more likely (IMHO) to occur in "real" code. Here's a second pass at it, with a bit of cleanup. It looks like I've created a cycle between the QWidget (whose destroyed signal refers to foo) and the function foo (which retains a reference to the QWidget). When Python breaks the cycle during its garbage collection, it finalizes the QWidget, which invokes foo, which causes a crash. The QApplication instance, however, is still valid and has not been either finalized (that is, Python's __del__) or destroyed (the C++ destructor). Any thoughts?</div><div><br></div><div><div><font face="monospace, monospace">import sys</font></div><div><font face="monospace, monospace">import os</font></div><div><font face="monospace, monospace">import platform</font></div><div><font face="monospace, monospace">import gc</font></div><div><font face="monospace, monospace">import sip</font></div><div><font face="monospace, monospace">from PyQt5.QtWidgets import QApplication, QWidget</font></div><div><font face="monospace, monospace">from PyQt5.QtCore import QT_VERSION_STR</font></div><div><font face="monospace, monospace">from PyQt5.Qt import PYQT_VERSION_STR</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">app = None</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">DEBUG = False</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">if DEBUG:</font></div><div><font face="monospace, monospace">    def printDestroyed(qObject):</font></div><div><font face="monospace, monospace">        qObjectStr = str(qObject)</font></div><div><font face="monospace, monospace">        def destroyed():</font></div><div><font face="monospace, monospace">            print('destroyed {}'.format(qObjectStr))</font></div><div><font face="monospace, monospace">        qObject.destroyed.connect(destroyed)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    class QApplicationF(QApplication):</font></div><div><font face="monospace, monospace">        def __del__(self):</font></div><div><font face="monospace, monospace">            print('finalized {}'.format(self))</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    class QWidgetF(QWidget):</font></div><div><font face="monospace, monospace">        def __del__(self):</font></div><div><font face="monospace, monospace">            print('finalized {}'.format(self))</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    def checkLeaks():</font></div><div><font face="monospace, monospace">        for o in gc.get_objects():</font></div><div><font face="monospace, monospace">            try:</font></div><div><font face="monospace, monospace">                if not sip.isdeleted(o):</font></div><div><font face="monospace, monospace">                    sip.dump(o)</font></div><div><font face="monospace, monospace">            except TypeError:</font></div><div><font face="monospace, monospace">                pass</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">else:</font></div><div><font face="monospace, monospace">    def printDestroyed(_): pass</font></div><div><font face="monospace, monospace">    QApplicationF = QApplication</font></div><div><font face="monospace, monospace">    QWidgetF = QWidget</font></div><div><font face="monospace, monospace">    def checkLeaks(): pass</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">def foo(x):</font></div><div><font face="monospace, monospace">    return lambda: x</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">def qtMain(doCrash):</font></div><div><font face="monospace, monospace">    global app</font></div><div><font face="monospace, monospace">    app = QApplicationF(sys.argv)</font></div><div><font face="monospace, monospace">    printDestroyed(app)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    w = QWidgetF()</font></div><div><font face="monospace, monospace">    printDestroyed(w)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    param = w if doCrash else 1</font></div><div><font face="monospace, monospace">    w.destroyed.connect(foo(param))</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">def gcCrash(createCycle, doCollect):</font></div><div><font face="monospace, monospace">    qtMain(createCycle)</font></div><div><font face="monospace, monospace">    checkLeaks()</font></div><div><font face="monospace, monospace">    gc.collect(doCollect)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">if __name__ == '__main__':</font></div><div><font face="monospace, monospace">    # Both must be True for a crash.</font></div><div><font face="monospace, monospace">    gcCrash(True, True)</font></div></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 10, 2016 at 2:26 PM, Baz Walter <span dir="ltr"><<a href="mailto:bazwal@ftml.net" target="_blank">bazwal@ftml.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 10/02/16 18:44, Phil Thompson wrote:<br>
> On 10 Feb 2016, at 6:08 pm, Baz Walter <<a href="mailto:bazwal@ftml.net">bazwal@ftml.net</a>> wrote:<br>
>><br>
>> On 10/02/16 17:24, Phil Thompson wrote:<br>
>><br>
</span><span class="">>> Which works okay, but still dumps core on exit, which I don't<br>
>> understand. Any ideas why that is?<br>
><br>
> With your changes it works fine for me (on OSX), no crash on exit.<br>
><br>
> Phil<br>
><br>
<br>
</span>I'm testing on Linux, but can't get any useful back-trace. The only clue<br>
is that it seems to be another one of those crashes that occurs in the<br>
QXcbEventReader thread (i.e. like the QtWebEngine crashes on exit). If I<br>
don't show() the widget, there's no crash.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Regards<br>
Baz Walter<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
PyQt mailing list    <a href="mailto:PyQt@riverbankcomputing.com">PyQt@riverbankcomputing.com</a><br>
<a href="https://www.riverbankcomputing.com/mailman/listinfo/pyqt" rel="noreferrer" target="_blank">https://www.riverbankcomputing.com/mailman/listinfo/pyqt</a></div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">Bryan A. Jones, Ph.D.<br>Associate Professor<br>Department of Electrical and Computer Engineering<br>231 Simrall / PO Box 9571<br>Mississippi State University<br>Mississippi state, MS 39762<br><a href="http://www.ece.msstate.edu/~bjones" target="_blank">http://www.ece.msstate.edu/~bjones</a><br>bjones AT ece DOT msstate DOT edu<br>voice 662-325-3149<br>fax 662-325-2298<br><br>Our Master, Jesus Christ, is on his way. He'll show up right on<br>time, his arrival guaranteed by the Blessed and Undisputed Ruler,<br>High King, High God.<br>- 1 Tim. 6:14b-15 (The Message)<br></div>
</div>