How to do workaround MATLAB crash in set(gcf,'C​urrentAxes​',ax1)?

14 vues (au cours des 30 derniers jours)
Patrik Ek
Patrik Ek le 5 Nov 2014
Hi,
I have used matlab for a long time and always liked it. That to say until version 2014b. This version seems to have severe concurrency problems. I got this crash today:
Error using matlab.ui.Figure/set
Axes must be an existing child of figure.
Error in nrOfUEs (line 87)
set(gcf,'CurrentAxes',ax1);
Error in Throughput_stats (line 1071)
nrOfUEs(Stop, NrUE);
Error in femto_all_thrp (line 60)
Throughput_stats(...
87 set(gcf,'CurrentAxes',ax1);
But in debug mode right after this crash manually typing
K>> set(gcf,'CurrentAxes',ax1);
Does not give an error. There are a few possible causes to this problem, depending on what the error message really mean in matlab:
1) The handle is not created
This is however unlikely since the loop
while ~ishandle(ax1)
fprintf('waiting...\n');
end
is not triggered.
2) The handle is modified in row 79 and is thus locked with a mutex lock or other preferred lock
3) The axes are modified, and thus not accessible
There may (mostl likely) also be other possible issues with this. The question is
Are there any workarounds to this problem?
My relevant code row 78-87
78 % Link the x-axes (for zooming purpouse)
79 linkaxes([ax1 ax2], 'x');
81 % Set the original axes to be the current (in case you want to modify it or
82 % anythin)
83 while ~ishandle(ax1)
84 fprintf('waiting...\n');
85 end
87 set(gcf,'CurrentAxes',ax1);

Réponse acceptée

Patrik Ek
Patrik Ek le 5 Nov 2014
I just found an answer to the problem, but I still wanted to publish this question to raise the problem. I would not be able to send a bug report to this problem since I would in that case have to submit company secrets. Also this would not come until earliest update 2015b.
The workaround I found was:
while ( ~any( get(gcf,'Children')==ax1 ) )
pause(1);
fprintf('waiting...\n'); % Not necessary, but this helps to see if the code enters the loop
end
This gives the other thread time to finish the GUI.
I would be happy for suggestions about title to reach a larger audiance.
Good Luck All!

Plus de réponses (2)

Mike Garrity
Mike Garrity le 5 Nov 2014
From the error message, my guess is that you've got multiple figures, and gcf isn't what you think it is.
Perhaps something more like this would be appropriate:
set(ancestor(ax1,'figure'),'CurrentAxes',ax1)
That's saying that you want ax1 to be the CurrentAxes of its figure, rather than saying that you want ax1 to be the CurrentAxes of whatever figure happens to be gcf at the moment.
  3 commentaires
Mike Garrity
Mike Garrity le 14 Nov 2014
No, that kind of assumption about which figure is gcf has never really been safe. You should always check which figure is current instead of assuming.
Consider the following example:
nfigs = 10;
figs = [];
pos = get(0,'DefaultFigurePosition');
for i=1:nfigs
figs = [figs, figure('Position',pos + i*[10 -10 0 0])];
end
for i=1:100000
f = figs(randi(nfigs,1));
figure(f);
pause(.1);
if gcf ~= f
disp wrong
end
end
While this is running, try clicking on different windows, or if you're on Windows, try using ALT-TAB. You'll see that in any version of MATLAB you'll occasionally see that "wrong" message. That's because the current figure can be set in more than one way. The MATLAB code that is calling figure can't safely make assumptions about what's happening on the other side, and that call to pause lets events in from the other side.
I think that it is true that this might happen more frequently in R2014b. That's because more of the graphics work has been moved off of the compute thread. But the possibility that gcf changed during the pause is not new.
The little code snippet I gave you will always set the CurrentAxes property on the correct figure, regardless of whether that changed during the pause, because the call to ancestor always returns the figure which ax1 belongs to, even if that's not gcf.
Patrik Ek
Patrik Ek le 8 Déc 2014
I am not sure if this s really the cause. What I know this requires some user interaction, what I did was actually that I started the program and not touching anything since I know that activating different figures can cause the current figure to change. The thing that were a bit disturbing was that using code that have been run for many years and that have never crashed so far suddenly crashed. What also was strange was that waiting until the handle existed worked.
To clarify. Without me touching the mouse, the keyboard, while running the given code on a newly restarted computer, got this error. What I had done was creating the figure in question, creating some plots in the figure and then in the end set ax1. It feels strange that the current figure should then not be the one that I required here. It is also strange that without further user interaction suddenly after less than 0.2 seconds (lowest time tested) suddenly getting the right figure as gcf. It feels as if something is fishy here, but I am not sure what.

Connectez-vous pour commenter.


Kelly Kearney
Kelly Kearney le 8 Déc 2014
I'm not sure if it's entirely related, but I have also found the need to throw a lot of drawnow commands into some of my code in order for it to be compatible with R2014b.
Same basic symptoms... a command that accesses the properties of a graphics object would return an error, but if I placed a breakpoint on that line, the error would not be reproduced. Adding a drawnow just before the command fixed the issue by forcing a mid-calculation render, but it's not an ideal solution (since in my case this results in intermediate-stage rendering, i.e. graphics objects that flash on and off as they're being repositioned, while older versions were able to do this repositioning behind the scenes).
When I submitted a bug report about this, they said this wasn't a bug but just a "timing issue". My takeaway was that at least for now, when programming for 2014b, never assume that a graphics-related line of code will be fully executed before the program moves on to the next graphics-related command, unless you explicitly force it with a drawnow.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by