let examples have a chance to exit normally#1605
Conversation
|
So ColorButton.py seems to be fixed by removing the reference to the child widget from the main script. |
|
Segfault in JoystickButton.py is fixed by wrapping things up into a class. So at least one class of segfaults could be fixed in a similar way. |
|
the macOS Failure... I've seen this periodically, I have no clue how to fix this. One potential action is to migrate our macOS CI platform to Big Sur (macOS 11) from Catalina (10.15); there may be other downsides with that, and that does not ensure this issue won't be resolved. Thanks for tackling this @pijyoi Please let me know if there is a specific test you'd like me to try and patch up. I have access to macOS and Windows platforms, I can get access to an ubuntu platform too if needed. |
d4b22bb to
efa7ea5
Compare
|
Console.py creates a cyclic self reference, preventing cleanup. Was introduced in 8aec44d as a feature, so this fix would break that usage.
It's unlikely that I would be able to see this through. Perhaps create a "needs help" issue? From what I can see,
|
|
Perhaps a decent way to do it would be to open 1 issue per example that
segfaults, I can attach a milestone to them, and close off each issue as a
fix is merged?
…On Tue, Feb 23, 2021 at 17:25 pijyoi ***@***.***> wrote:
Console.py creates a cyclic self reference, preventing cleanup. Was
introduced in 8aec44d
<8aec44d>
as a feature, so this fix would break that usage.
Thanks for tackling this @pijyoi <https://github.com/pijyoi> Please let
me know if there is a specific test you'd like me to try and patch up. I
have access to macOS and Windows platforms, I can get access to an ubuntu
platform too if needed.
It's unlikely that I would be able to see this through. Perhaps create a
"needs help" issue?
Rewriting the examples that segfault would be a huge effort and it's
likely that some bugs or change in behavior would be introduced,
particularly if the functionality involved isn't even used by the developer
in their own programs.
From what I can see,
1. the segfaults affect Python 3.8, PySide2, Windows and Linux.
2. PyQt doesn't segfault, probably because of this mitigation:
https://www.riverbankcomputing.com/static/Docs/PyQt5/gotchas.html#crashes-on-exit
3. all the 3D Graphics examples segfault.
4. Linux has a lot more segfaults
- The Console.py commit fixes the segfault for Windows but not for
Linux, so some other thing is going on for Linux
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1605 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAE5Z7VJRB5PCJQYE4AQHP3TARIRTANCNFSM4YB3N6VQ>
.
|
efa7ea5 to
b1d14ca
Compare
|
The segfaults were git bisected to a change made in #1302. Inheriting from QApplication, that is. |
|
Gotta love it when a PR you created/merged causes breakage that's discovered later... Is it just the inheritance that's causing the segfault, or is it something we're doing within that inheritance that's driving it. For example, is there still a segfault if we just have? class App(QtGui.QApplication):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)I can look into this later too, just might take me a day or two... Thanks for the tip with checking for newer versions of python. |
b1d14ca to
c6449fa
Compare
I didn't try it but it seems unnecessary to sub-class QApplication which is a singleton. In my last commit, I connected the signal to a standalone function. |
🤯 ...it didn't dawn on me that |
|
That deduplication commit... why didn't I think of that when I wrote it, ...instead of copy-pasting.... |
|
@pijyoi this PR looks great to me. I'll give time for some other folks to look at this before I merge; but this should make a significant improvement to the reliability ... the |
|
Some segfaults now on macOS PyQt: ScatterPlot.py, VideoSpeedTest.py, ViewBoxFeatures.py |
|
The I haven't figured out how to handle this issue and despite seeing the same error in other repositories, I have yet to see a fix. Only idea I have is rolling our macOS test image from 10.15, to 11.0. Another option is to run I'll try and investigate the issue on Windows in a bit. |
|
Can't replicate the windows failure either; that's annoying... for the fun of it, I'll re-run the CI and see what happens. |
|
Well on rerun, everything passes.... I feel so conflicted about this. EDIT: will re-run again momentarily |
|
I'm going to re-run the CI pipeline a few times to see if we can get a list of items that are segfaulting. I am suspicious that the items that are segfaulting have |
|
I've re-ran the CI suite almost 10 times now... The failures I've seen are:
@pijyoi I would recommend not installing |
|
Go ahead, make the changes.
…On Sun, 28 Feb 2021, 05:16 Ogi Moore, ***@***.***> wrote:
I've re-ran the CI suite almost 10 times now... The failures I've seen are:
- VideoSpeedTest.py x2 (both on Windows - PyQt5 5.15/Python 3.8)
- PanningPlot.py (Windows - PyQt5 5.15/Python 3.8)
- test_interpolateArray_order0 worked crashed during this test
- ViewBoxFeatures.py macOS PyQt5 5.15/Python 38 and Windows - PyQt6 -
Python 3.9
- ScatterPlot Ubuntu PyQt6/Python 3.9
- ScrollingPlots.py - macOS PySide6/Python 3.9
- test_ref_cycles.py::test_ImageView xdist worker crashed (also got
weird exception from the coverage tool)
@pijyoi <https://github.com/pijyoi> I would recommend *not* installing
pytest-xdist and pytest-cov, removing the -n auto, and removing the calls
for coverage to minimize other factors that might be influencing these
tests. Let me know if you'd like me to make these changes on your branch.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1605 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAUIWA45R6TZIOIP3H3G65DTBFOMDANCNFSM4YB3N6VQ>
.
|
|
I branched off of your branch, and am testing some stuff out on my fork; I'm developing confidence that I've fixed the segfault with def closeEvent(self, event):
self.timer.disconnect(self.update)
return super().closeEvent(event)Edit: when re-enabling this method, appears that the |
|
I think I may have fixed up The example hasn't failed on me since I made this change. w1.setParent(view)
w2.setParent(view)
w3.setParent(view)
w4.setParent(view)
s1.setParent(view)
s2.setParent(view)
s3.setParent(view)
s4.setParent(view)Turns out, that EDIT: I suspect this same issue is what occasionally makes |
|
What I don't know how to do easily is disconnect the timer on examples like I suppose we could add a signal ( EDIT: I'm now experimenting with setting the parent object of the timer to the graphics window we're displaying, hopefully that will work. |
|
The following line from https://doc.qt.io/qt-5/qtimer.html makes me uneasy. It's like saying that it's possible for your idle timer to fire after some gui objects have been torn down. |
I suspect that's exactly what it's saying. I suppose we should change our all our instances of |
|
https://wiki.qt.io/Timers#Windows |
The keyword here being "method", i.e. nothing related to Qt instantiated in module namespace. So you would need to wrap everything up in a class. Alternatively, I was trying to cause destruction of the imported module with the
# file MyClass.py
class MyClass:
def __init__(self):
pass
def __del__(self):
print('__del__')
win = MyClass()# file import_MyClass.py
import sys
import gc
import MyClass
print('A')
del sys.modules['MyClass']
del MyClass
gc.collect()
print('B') |
|
You may need to also do a call the collect function of th garbage collector, but that has other unfortunate side effects. |
|
the latest commit causes failures for PyQt Linux and macOS specifically for the 2 examples that make use of QTimer.singleShot()
This seems to show that PyQt binding executes the event loop upon application shutdown. |
|
hi @pijyoi thanks so much for sticking with this... I'm trying to follow along, and when you think you have this in a "ready to merge" state, I'll likely have more questions. The one thing that sticks out at me about the diff as it stands right now are these lines: if hasattr({1}, 'MainWindow'):
pg.mkQApp()
win = {1}.MainWindow()Is there something special about |
the idea was that examples that have sub-classed QMainWindow are likely those which have wrapped everything up nicely and do not instantiate things on import. |
For the record, I have no problem modifying the examples so they are all bundled into encompassing classes, especially as that is how Qt is generally used anyway (but I fully recognize that is well outside the scope of this PR). |
|
To summarize, there are 2 main fixes going on here:
I have verified that the fix for (2) does not fix (1) |
cleanup imported module 1) instantiate MainWindow class if present 2) delete attributes from imported module when done
|
To not detract from the root issues described above, I have dropped from this PR the commits that change some examples to QMainWindow classes.
Should be ready for review. The "Disable coverage and xdist for troubleshooting" commit can be dropped later. |
|
@pijyoi This PR looks good to me; thank you so much for tracking these issues down. I don't know of any of the maintainers that think we have some great knowledge in the lifecycle of QObjects, so I'm inclined to say functionally things should remain as they are (minus my PR altering timer.setSingleShot(True)
# not using `timer.singleShot() because of persistence see PR #1605and App = QtWidgets.QApplication
# subclassing QApplication causes segfaults on python 3.8.7+(or something to that effect). I would remove my commit from your branch (it was put there to make tests more deterministic), but I have a reluctance to force-push on someone else's branch, so I'll leave that to you. |
On macOS and Linux with PyQt bindings, QTimer.singleShot continues to fire on python interpreter shutdown.
|
I think this is ready to merge. @ixjlyons @outofculture @ksunden you all have any other input? |
|
I found the other case I mentioned, macOS / Python 3.9 / PyQt6 |
|
I have seen output like this that got printed after the test results summary was shown on the console, was a bit confused as to what was going on. I wonder if this is a case of not having a good QObject parent <-> child relationship chain and things aren't closing out as they should on exit. In the cases I saw it, it didn't actually show any test failures... |
|
Would it be preferable to split this PR into 2? The first for the user-visible segfaults and the second for the CI-only segfaults (which are triggered by trying to let the examples end normally) The first should fix #1599 (comment) (Could you also verify that?) |
|
I'm fine keeping the PR together; I'll verify this fixes the issue I commented on before merging. |
|
Meant to merge this earlier this week, apologies for the wait. Thanks so much for this @pijyoi ! |


PR to demonstrate segfaults occurring for many examples if they are allowed to end normally.