Re: Crash-on-exit after call to app.processEvents()

Thomas Caswell <[email protected]> Mon, 25 May 2020 18:42:09 -0400
Newsgroups gmane.comp.python.pyqt-pykde
Message-ID <CAA48SF9hkU3sO=UeRHzXrfHtuUrXLXR2thOV2C9HwfJDzcYJoQ@mail.gmail.com>
--00000000000019a1d305a680b115
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

This is reminding me of the issues Armando raised with Matplotlib (
https://github.com/matplotlib/matplotlib/issues/14178 /
https://github.com/matplotlib/matplotlib/pull/14179).  I now understand why
Matplotlib (and IPython) holding references to the qApp can be problematic
(as in this case del ing app just drops your reference to it but does not
actually trigger the `__delete__` code because other parts of the codebase
are keeping it alive) if having a "live" app on process shut down can cause
problems.

My naive guess as to why calling `ProcessEvents` triggers the issue as that
it creates some extra state on at least the c++ side and we end up tearing
down the objects on the Python side in a different order than we need to on
the c++ side.  Oventually something winds up with a null pointer (because
there was a reference at the c++ level but not at the Python level) and
boom.  I stress that while that is where I would start looking to track
this down it is still very much a guess.

Tom

On Mon, May 25, 2020 at 5:36 PM Raymond Osborn <[email protected]> wrote:

> Hi Armando,
> Good to hear from you. I thought for a while that I had managed to fix it
> with the following code :
>
>     def main(filename=3DNone):
>         app =3D NXConsoleApp()
>         app.initialize(filename=3Dfilename)
>         app.start()
>         for w in QApplication.topLevelWindows():
>             del w
>         del app.window, app.app
>         sys.exit(0)
>
> It proved to be a false dawn - the problem started to recur again. I=E2=
=80=99ll
> see if your version catches things that mine missed, and let you know.
>
> I have spent a lot of time trying to cover up PyQt5 bugs in the past year=
.
> The problem is that I can=E2=80=99t guarantee that my users will have the=
 latest
> version of PyQt, so even if it is fixed in v5.14, I still have to patch t=
he
> code. I just have no idea why simply calling processEvents() triggers the
> bug. If I knew that, perhaps it would give some clue how to work around i=
t.
>
> Ray
>
>
> On May 25, 2020, at 3:38 PM, V. Armando Sole <[email protected]> wrote:
>
> Hi Ray,
>
> I do not know if it will help your case. I was getting rid of some crashe=
s
> on exit by deleting all widgets that had no parent. For instance, when
> closing the QMainWindow by doing:
>
>     def closeEvent(self, event):
>         if __name__ =3D=3D "__main__":
>             app =3D qt.QApplication.instance()
>             allWidgets =3D app.allWidgets()
>             for widget in allWidgets:
>                 try:
>                     # we cannot afford to crash here
>                     if id(widget) !=3D id(self):
>                         if widget.parent() is None:
>                             widget.close()
>                 except:
>                     _logger.debug("Error closing widget")
>         return qt.QMainWindow.closeEvent(self, event)
>
> Best regards,
>
> Armando
>
> On 25.05.2020 19:48, Raymond Osborn wrote:
>
> I added a call to QtWidgets.QApplication.instance().processEvents() in
> order to force adjustResize() to work when switching tabs (that's another
> story). It succeeded in fixing my resize issue, but now it triggers a
> segfault when I exit the application. This seemed to be related to the bu=
g
> described in
> https://www.riverbankcomputing.com/static/Docs/PyQt5/gotchas.html#crashes=
-on-exit.
> One fix, suggested by @ekhumoro on stackoverflow (
> https://stackoverflow.com/questions/59120337/why-does-pyqt-sometimes-cras=
h-on-exit)
> was to delete the main window and the app first, but that doesn't seem to
> fix it. I am running PyQt 5.12 because that is the last version supported
> by conda, so I can't test the one-exit fix in v5.13, and my users probabl=
y
> wouldn't have it installed anyway. It happens on Macs and linux.
>
> What I am asking is if there are additional things to try in addition to
> @ekhumoro's suggestion? Basically he suggests doing something like:
>
>
> def main():
>     app =3D QApplication(sys.argv)
>     main_window =3D MainWindow()
>     main_window.show()
>     app.exec_()
>     # ensure correct deletion order
>     del main_window, app
>
> Does anyone understand why the crash only occurs if I have calls to
> processEvents() in the code? It never happens when I remove them.
>
> Thanks,
> Ray
>
>
>
>
>

--=20
Thomas Caswell
[email protected]

--00000000000019a1d305a680b115
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">This is reminding me of the issues Armando raised with Mat=
plotlib (<a href=3D"https://github.com/matplotlib/matplotlib/issues/14178">=
https://github.com/matplotlib/matplotlib/issues/14178</a>=C2=A0/=C2=A0<a hr=
ef=3D"https://github.com/matplotlib/matplotlib/pull/14179">https://github.c=
om/matplotlib/matplotlib/pull/14179</a>).=C2=A0 I now understand why Matplo=
tlib (and IPython) holding references to the qApp can be problematic (as in=
 this case del ing app just drops your reference to it but does not actuall=
y trigger the `__delete__` code because=C2=A0other parts of the codebase ar=
e keeping it alive) if having a &quot;live&quot; app on process shut down c=
an cause problems.<div><br></div><div>My naive guess as to why calling `Pro=
cessEvents` triggers the issue as that it creates some extra state on at le=
ast the c++ side and we end up tearing down the objects on the Python side =
in a different order than we need to on the c++ side.=C2=A0 Oventually some=
thing winds up with a null pointer (because there was a reference at the c+=
+ level but not at the Python level) and boom.=C2=A0 I stress that while th=
at is where I would start looking to track this down it is still very much =
a guess.<br><div><div><br><div>Tom</div></div></div></div></div><br><div cl=
ass=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Mon, May 25, 2=
020 at 5:36 PM Raymond Osborn &lt;<a href=3D"mailto:[email protected]">rayo=
[email protected]</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddi=
ng-left:1ex"><div style=3D"overflow-wrap: break-word;">Hi Armando,<div>Good=
 to hear from you. I thought for a while that I had managed to fix it with =
the following code :</div><div><br></div><div><div>=C2=A0 =C2=A0 def main(f=
ilename=3DNone):</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 app =3D NXConsoleApp=
()</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 app.initialize(filename=3Dfilename=
)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 app.start()</div><div>=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 for w in QApplication.topLevelWindows():</div><div>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 del w</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 del app.window, app.app</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 sys.exit(=
0)</div><div><br></div><div>It proved to be a false dawn - the problem star=
ted to recur again. I=E2=80=99ll see if your version catches things that mi=
ne missed, and let you know.</div><div><br></div><div>I have spent a lot of=
 time trying to cover up PyQt5 bugs in the past year. The problem is that I=
 can=E2=80=99t guarantee that my users will have the latest version of PyQt=
, so even if it is fixed in v5.14, I still have to patch the code. I just h=
ave no idea why simply calling processEvents() triggers the bug. If I knew =
that, perhaps it would give some clue how to work around it.</div><div><br>=
</div><div>Ray</div><div><br></div><div><br><blockquote type=3D"cite"><div>=
On May 25, 2020, at 3:38 PM, V. Armando Sole &lt;<a href=3D"mailto:sole@esr=
f.fr" target=3D"_blank">[email protected]</a>&gt; wrote:</div><br><div><div styl=
e=3D"font-size:10pt;font-family:Verdana,Geneva,sans-serif"><p>Hi Ray,</p><p=
>I do not know if it will help your case. I was getting rid of some crashes=
 on exit by deleting all widgets that had no parent. For instance, when clo=
sing the QMainWindow by doing:</p><p>=C2=A0=C2=A0=C2=A0 def closeEvent(self=
, event):<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if __name__ =3D=3D =
&quot;__main__&quot;:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 app =3D qt.QApplication.instance()<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 allWidgets =3D app.allWidg=
ets()<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 for widget in allWidgets:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 try:<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 # we cannot afford to crash here<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 if id(widget) !=3D id(self):<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if widget.parent() is None:<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 widget.close()<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 except:<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 _logger.debug(&quot;Error closing widget&quot;)<br=
>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return qt.QMainWindow.closeEven=
t(self, event)</p><p>Best regards,</p><p>Armando</p><p>On 25.05.2020 19:48,=
 Raymond Osborn wrote:</p>
<blockquote type=3D"cite" style=3D"padding:0px 0.4em;border-left:2px solid =
rgb(16,16,255);margin:0px">I added a call to=C2=A0QtWidgets.QApplication.in=
stance().processEvents() in order to force adjustResize() to work when swit=
ching tabs (that&#39;s another story). It succeeded in fixing my resize iss=
ue, but now it triggers a segfault when I exit the application. This seemed=
 to be related to the bug described in=C2=A0<a href=3D"https://www.riverban=
kcomputing.com/static/Docs/PyQt5/gotchas.html#crashes-on-exit" target=3D"_b=
lank">https://www.riverbankcomputing.com/static/Docs/PyQt5/gotchas.html#cra=
shes-on-exit</a>. One fix, suggested by @ekhumoro on stackoverflow (<a href=
=3D"https://stackoverflow.com/questions/59120337/why-does-pyqt-sometimes-cr=
ash-on-exit" target=3D"_blank">https://stackoverflow.com/questions/59120337=
/why-does-pyqt-sometimes-crash-on-exit</a>) was to delete the main window a=
nd the app first, but that doesn&#39;t seem to fix it. I am running PyQt 5.=
12 because that is the last version supported by conda, so I can&#39;t test=
 the one-exit fix in v5.13, and my users probably wouldn&#39;t have it inst=
alled anyway. It happens on Macs and linux.
<div>=C2=A0</div>
<div>What I am asking is if there are additional things to try in addition =
to @ekhumoro&#39;s suggestion? Basically he suggests doing something like:<=
/div>
<div>=C2=A0</div>
<div>
<pre style=3D"margin-top:0px;margin-bottom:1em;padding:12px 8px;border:0px;=
font-family:Consolas,Menlo,Monaco,&quot;Lucida Console&quot;,&quot;Liberati=
on Mono&quot;,&quot;DejaVu Sans Mono&quot;,&quot;Bitstream Vera Sans Mono&q=
uot;,&quot;Courier New&quot;,monospace,sans-serif;font-stretch:inherit;line=
-height:inherit;font-size:13px;vertical-align:baseline;box-sizing:inherit;w=
idth:auto;max-height:600px;overflow:auto;border-radius:3px;color:rgb(36,39,=
41)"><code style=3D"margin:0px;padding:0px;border:0px;font-family:Consolas,=
Menlo,Monaco,&quot;Lucida Console&quot;,&quot;Liberation Mono&quot;,&quot;D=
ejaVu Sans Mono&quot;,&quot;Bitstream Vera Sans Mono&quot;,&quot;Courier Ne=
w&quot;,monospace,sans-serif;font-style:inherit;font-variant-caps:inherit;f=
ont-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:=
inherit;white-space:inherit"><span style=3D"margin:0px;padding:0px;border:0=
px;font-family:inherit;font-style:inherit;font-variant-caps:inherit;font-st=
retch:inherit;line-height:inherit;vertical-align:baseline;box-sizing:inheri=
t">def</span><span style=3D"margin:0px;padding:0px;border:0px;font-family:i=
nherit;font-style:inherit;font-variant-caps:inherit;font-stretch:inherit;li=
ne-height:inherit;vertical-align:baseline;box-sizing:inherit"> main</span><=
span style=3D"margin:0px;padding:0px;border:0px;font-family:inherit;font-st=
yle:inherit;font-variant-caps:inherit;font-stretch:inherit;line-height:inhe=
rit;vertical-align:baseline;box-sizing:inherit">():</span><span style=3D"ma=
rgin:0px;padding:0px;border:0px;font-family:inherit;font-style:inherit;font=
-variant-caps:inherit;font-stretch:inherit;line-height:inherit;vertical-ali=
gn:baseline;box-sizing:inherit">
    app </span><span style=3D"margin:0px;padding:0px;border:0px;font-family=
:inherit;font-style:inherit;font-variant-caps:inherit;font-stretch:inherit;=
line-height:inherit;vertical-align:baseline;box-sizing:inherit">=3D</span><=
span style=3D"margin:0px;padding:0px;border:0px;font-family:inherit;font-st=
yle:inherit;font-variant-caps:inherit;font-stretch:inherit;line-height:inhe=
rit;vertical-align:baseline;box-sizing:inherit"> </span><span style=3D"marg=
in:0px;padding:0px;border:0px;font-family:inherit;font-style:inherit;font-v=
ariant-caps:inherit;font-stretch:inherit;line-height:inherit;vertical-align=
:baseline;box-sizing:inherit;color:rgb(43,145,175)">QApplication</span><spa=
n style=3D"margin:0px;padding:0px;border:0px;font-family:inherit;font-style=
:inherit;font-variant-caps:inherit;font-stretch:inherit;line-height:inherit=
;vertical-align:baseline;box-sizing:inherit">(</span><span style=3D"margin:=
0px;padding:0px;border:0px;font-family:inherit;font-style:inherit;font-vari=
ant-caps:inherit;font-stretch:inherit;line-height:inherit;vertical-align:ba=
seline;box-sizing:inherit">sys</span><span style=3D"margin:0px;padding:0px;=
border:0px;font-family:inherit;font-style:inherit;font-variant-caps:inherit=
;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-sizin=
g:inherit">.</span><span style=3D"margin:0px;padding:0px;border:0px;font-fa=
mily:inherit;font-style:inherit;font-variant-caps:inherit;font-stretch:inhe=
rit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">argv</s=
pan><span style=3D"margin:0px;padding:0px;border:0px;font-family:inherit;fo=
nt-style:inherit;font-variant-caps:inherit;font-stretch:inherit;line-height=
:inherit;vertical-align:baseline;box-sizing:inherit">)</span><span style=3D=
"margin:0px;padding:0px;border:0px;font-family:inherit;font-style:inherit;f=
ont-variant-caps:inherit;font-stretch:inherit;line-height:inherit;vertical-=
align:baseline;box-sizing:inherit">
    main_window </span><span style=3D"margin:0px;padding:0px;border:0px;fon=
t-family:inherit;font-style:inherit;font-variant-caps:inherit;font-stretch:=
inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">=3D=
</span><span style=3D"margin:0px;padding:0px;border:0px;font-family:inherit=
;font-style:inherit;font-variant-caps:inherit;font-stretch:inherit;line-hei=
ght:inherit;vertical-align:baseline;box-sizing:inherit"> </span><span style=
=3D"margin:0px;padding:0px;border:0px;font-family:inherit;font-style:inheri=
t;font-variant-caps:inherit;font-stretch:inherit;line-height:inherit;vertic=
al-align:baseline;box-sizing:inherit;color:rgb(43,145,175)">MainWindow</spa=
n><span style=3D"margin:0px;padding:0px;border:0px;font-family:inherit;font=
-style:inherit;font-variant-caps:inherit;font-stretch:inherit;line-height:i=
nherit;vertical-align:baseline;box-sizing:inherit">()</span><span style=3D"=
margin:0px;padding:0px;border:0px;font-family:inherit;font-style:inherit;fo=
nt-variant-caps:inherit;font-stretch:inherit;line-height:inherit;vertical-a=
lign:baseline;box-sizing:inherit">
    main_window</span><span style=3D"margin:0px;padding:0px;border:0px;font=
-family:inherit;font-style:inherit;font-variant-caps:inherit;font-stretch:i=
nherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">.</s=
pan><span style=3D"margin:0px;padding:0px;border:0px;font-family:inherit;fo=
nt-style:inherit;font-variant-caps:inherit;font-stretch:inherit;line-height=
:inherit;vertical-align:baseline;box-sizing:inherit">show</span><span style=
=3D"margin:0px;padding:0px;border:0px;font-family:inherit;font-style:inheri=
t;font-variant-caps:inherit;font-stretch:inherit;line-height:inherit;vertic=
al-align:baseline;box-sizing:inherit">()</span><span style=3D"margin:0px;pa=
dding:0px;border:0px;font-family:inherit;font-style:inherit;font-variant-ca=
ps:inherit;font-stretch:inherit;line-height:inherit;vertical-align:baseline=
;box-sizing:inherit">
    app</span><span style=3D"margin:0px;padding:0px;border:0px;font-family:=
inherit;font-style:inherit;font-variant-caps:inherit;font-stretch:inherit;l=
ine-height:inherit;vertical-align:baseline;box-sizing:inherit">.</span><spa=
n style=3D"margin:0px;padding:0px;border:0px;font-family:inherit;font-style=
:inherit;font-variant-caps:inherit;font-stretch:inherit;line-height:inherit=
;vertical-align:baseline;box-sizing:inherit">exec_</span><span style=3D"mar=
gin:0px;padding:0px;border:0px;font-family:inherit;font-style:inherit;font-=
variant-caps:inherit;font-stretch:inherit;line-height:inherit;vertical-alig=
n:baseline;box-sizing:inherit">()</span><span style=3D"margin:0px;padding:0=
px;border:0px;font-family:inherit;font-style:inherit;font-variant-caps:inhe=
rit;font-stretch:inherit;line-height:inherit;vertical-align:baseline;box-si=
zing:inherit">
    </span><span style=3D"margin:0px;padding:0px;border:0px;font-family:inh=
erit;font-style:inherit;font-variant-caps:inherit;font-stretch:inherit;line=
-height:inherit;vertical-align:baseline;box-sizing:inherit"># ensure correc=
t deletion order</span><span style=3D"margin:0px;padding:0px;border:0px;fon=
t-family:inherit;font-style:inherit;font-variant-caps:inherit;font-stretch:=
inherit;line-height:inherit;vertical-align:baseline;box-sizing:inherit">
    </span><span style=3D"margin:0px;padding:0px;border:0px;font-family:inh=
erit;font-style:inherit;font-variant-caps:inherit;font-stretch:inherit;line=
-height:inherit;vertical-align:baseline;box-sizing:inherit">del</span><span=
 style=3D"margin:0px;padding:0px;border:0px;font-family:inherit;font-style:=
inherit;font-variant-caps:inherit;font-stretch:inherit;line-height:inherit;=
vertical-align:baseline;box-sizing:inherit"> main_window</span><span style=
=3D"margin:0px;padding:0px;border:0px;font-family:inherit;font-style:inheri=
t;font-variant-caps:inherit;font-stretch:inherit;line-height:inherit;vertic=
al-align:baseline;box-sizing:inherit">,</span><span style=3D"margin:0px;pad=
ding:0px;border:0px;font-family:inherit;font-style:inherit;font-variant-cap=
s:inherit;font-stretch:inherit;line-height:inherit;vertical-align:baseline;=
box-sizing:inherit"> app</span></code></pre>
<div>Does anyone understand why the crash only occurs if I have calls to pr=
ocessEvents() in the code? It never happens when I remove them.</div>
</div>
<div>=C2=A0</div>
<div>Thanks,</div>
<div>Ray</div>
<div>=C2=A0</div>
<div>=C2=A0</div>
</blockquote>
</div>
</div></blockquote></div><br></div></div></blockquote></div><br clear=3D"al=
l"><div><br></div>-- <br><div dir=3D"ltr" class=3D"gmail_signature">Thomas =
Caswell<br><a href=3D"mailto:[email protected]" target=3D"_blank">tcaswell=
@gmail.com</a></div>

--00000000000019a1d305a680b115--