-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fix macosx segfault #17084
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix macosx segfault #17084
Conversation
If you delete the figure, and run a gc, does it also crash? As you noted, the code in |
@QuLogic I'm not sure how to do this. I tried with the following code (which works on import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.show(block=False)
plt.close(fig)
del fig However, |
My thought is either add |
No, this doesn't trigger the segfault. |
I think
And running:
Nothing prints until
We see:
Commenting this line:
Makes the list empty, but it's still not GC'ed. Not sure why that would be, maybe someone wants to look deeper. But at least this suggests to me that the Also perhaps when exiting (which does indeed cause it to get GC'ed and print) the order of cleanup is different in a way that does not cause a segfault -- you could try printing messages for |
Figures should be GC'able once closed and unreferenced, but I guess that's a separate issue from this one. Maybe adding a |
I don't quite understand why there are so many There are three situations where this might be necessary, but none of them apply to matplotlib AFAICT. Actually, I removed all |
Reading those docs you linked, I'm inclined to agree with your conclusions. I'd feel more confident if we could do a stress test of the memory usage, though. |
Ah, there's one small bug in that test; you need to delete
or never create it:
|
I'm not sure how to properly stress test this, but I've compared a memory profile using the following code snippet for both this branch and master: import tracemalloc
from functools import partial
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use("macosx")
print(matplotlib.__version__)
def close_event(event, fig):
plt.close(fig)
snapshot1 = tracemalloc.take_snapshot()
for n in range(1000):
fig = plt.figure()
close_callback = partial(close_event, fig=fig)
fig.canvas.mpl_connect("close_event", close_callback)
plt.show(block=False) # block=True works
plt.close(fig)
snapshot2 = tracemalloc.take_snapshot()
diff = snapshot2.compare_to(snapshot1, 'lineno')
for stat in diff[:10]:
print(stat) Both branches show the same difference (+2156 KiB) when comparing before and after creating and closing 1000 figures. Here's the output for this branch:
And this is master:
However, I'm not sure if (1) I'm comparing memory usage correctly, and (2) I'm correctly creating and closing figures in order to test what I want to test. |
b96da85
to
af58544
Compare
I am inclined to merge this conditional on one of our OSX based developers testing it locally The autorelease pools may be left over from porting the previous mac backend (which had it's own renderer) to one the current version that uses Agg to render the plot. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conditional on a committer with OSX verifying it works locally.
I think that's a good strategy. Even if it turns out that these changes do not work as expected in all scenarios, this can be quickly reverted, and users can always switch to the Qt5 backend. MNE devs recommend the PyQt5 backend even on macOS anyway, so in the long run it might be another option to change the default backend to PyQt5/PySide2 (QtPy) as is already the case on Linux and Windows. |
This seems to have broken the save dialog. The error below results from clicking on the save-file icon in the toolbar after making a trivial plot.
|
I can't reproduce the original crash, so I don't understand why this fixes it. But looking over the code it does appear to me that @tacaswell is right -- the autorelease pools were leftover from a previous implementation and are no longer serving a purpose. Also, by the way, the best way to create an autorelease pool is |
https://bugs.openjdk.java.net/browse/JDK-8227836 |
@lawrence-danna-apple after checking out from functools import partial
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use("macosx")
def close_event(event, fig):
plt.close(fig)
fig, ax = plt.subplots()
close_callback = partial(close_event, fig=fig)
fig.canvas.mpl_connect("close_event", close_callback)
plt.show(block=False) |
@efiring I cannot reproduce the error you encounter with the save dialog. I tried plotting a figure, clicking on save, and saving the figure, and everything worked (on master as well as on this branch). I guess this is a different issue not related to these changes here. |
I couldn't reproduce the original crash, either. Maybe there is some subtle timing involved, such that different hardware and/or OS versions behave differently. Two tests, A and B: for you, A fails and B passes; for me, A passes and B fails. Very strange. I'm on a Macbook pro 16", 6-core I7 at 2.6 GHz, Catalina 10.15.3. |
@efiring that's really strange, but with macOS you never know what they changed. I'm on 10.15.4 on an older MacBook Pro 15" mid-2014. You did try the example in script mode (#17084 (comment)), right? |
Yes, that's the one. But now I'm baffled. Repeating the tests, I still can't reproduce the original failure on master...but neither can I reproduce the save-dialog failure on your branch. I know it failed for me twice before. I'm stumped. |
Oh wow, did I fix this by accident too 😛? On a serious note, does #17263 address the dialog issue? This keeps happening to me, but most of the times I am on the wrong branch, forget to compile with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still can't reproduce my earlier problem with this, so let's assume it wasn't caused by this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to reproduce the crash from #17061, and this PR fixes the crash for me. I also tested with a variety of static, animation, and event handling examples; everything seems to be working fine.
Owee, I'm MrMeeseeks, Look at me. There seem to be a conflict, please backport manually. Here are approximate instructions:
And apply the correct labels and milestones. Congratulation you did some good work ! Hopefully your backport PR will be tested by the continuous integration and merged soon! If these instruction are inaccurate, feel free to suggest an improvement. |
Fix macosx segfault
Fixes #17061.
Please note that I don't know if these changes have adverse effects; they fix the segfault described in #17061 though. It would be great if someone familiar with the
macosx
backend source took a quick look.