- Undocumented Matlab - https://undocumentedmatlab.com -

A couple of internal Matlab bugs and workarounds

Posted By Yair Altman On June 12, 2013 | 4 Comments

Like any other major software package, Matlab too has its share of bugs [1]. If you ask me, the number of known bugs in Matlab is actually very small compared to the industry standard. Posting bugs online saves the support staff work on duplicates and provides immediate relief for users if the bug happens to have a posted workaround. It also increases transparency, which helps customer loyalty and confidence in the product. Serious engineering work that relies on Matlab for anything from designing cars and planes to trading on stock exchanges needs to be aware of all the current bugs, in order to avoid them in the production code.
Unfortunately, for some reason MathWorks does not publicize all the bugs that it knows about. I know this since there are multiple bugs that I have reported and were confirmed by the competent technical support staff, which do not appear on the online list. I do not know whether this is a deliberate MathWorks policy based on some criteria, but I would hope not and I hope it will be fixed. IMHO, Matlab in general is a very stable system that has absolutely nothing to be ashamed of in terms of the low number, and relatively low-impact, of its open bugs.
Today I write about two internal Matlab bugs that I have recently discovered and reported, along with their workarounds. None of them is really critical, but since neither appears in the official bug parade (as of today), I figured it would do some public good to post them here.

The clf function does not clear javacomponents (1-MNELS1)

The clf function clears the specified figure window (or the current figure [gcf] if no figure handle was specified as input) of any axes and GUI controls. At least, that what it is supposed to do and what it did pretty well until R2012a (Matlab 7.14). Apparently, in R2012b (Matlab 8.0) something broke and controls that are added to the figure window using the javacomponent function [2] are no longer cleared by clf – all the regular Matlab axes and uicontrols are deleted, but not the Java controls.

figure;
[jButton, hContainer] = javacomponent(javax.swing.JButton('Click'), [], gcf);
drawnow;
clf  % bug - clf does not delete the jButton/hContainer component from the figure

There are several possible workarounds:

  1. Keep the handles of all the relevant Java components, and then delete them directly:
    delete(hContainer)
  2. Use findobj to delete all components, rather than the clf function (we use setdiff to prevent deletion of the figure window itself):
    delete(setdiff(findobj(gcf),gcf))

Note that this bug does not occur when using HG2 [3]. However, for users who use the still-standard HG1, this bug is still unfixed as of Matlab R2013b Pre-release (which is now available for download for subscribed users).

GUIDE is unusable with dbstop if error (1-MH5KVI)

In R2013a (Matlab 8.1) I encounter a recurring error when attempting to inspect properties of objects in GUIDE, when “dbstop if error” is turned on.
The error happens when I have “dbstop if error” enabled. This is an enormously helpful [4] debugging tool, so I normally have it turned on in my startup.m file. But in R2013a, if I try to inspect an object’s properties in GUIDE, I see a problem. Matlab hits the breakpoint in %matlabroot%/toolbox/matlab/codetools/+internal/+matlab/+inspector/SceneViewerListener.m line 99 due to the fact that isvalid() is not defined for the object, and the inspector window remains blank.
How to reproduce:

  • run “dbstop if error” in the Matlab command window
  • open a *.fig file in the Matlab command window (e.g., “guide myApplication.fig“)
  • right-click and inspect the properties for an axes (for example)
  • wait for the breakpoint to occur – “K>>” in the command window; the Editor stops (green arrow) in SceneViewerListener.m line 99
  • an empty inspector window is displayed

Analysis:
Because SceneViewerListener is called from Java, not Matlab, the error is thrown as an exception that is trapped by the Java code and therefore does not appear to the user unless “dbstop if error” is on. Here is the full stack trace at the point of error (see this post [5] regarding how to generate the Java stack dump):

K>> dbstack
> In SceneViewerListener>SceneViewerListener.isBeingDeleted at 99
K>> st = java.lang.Thread.currentThread.getStackTrace; for idx = 2 : length(st), disp(st(idx)); end
com.mathworks.jmi.NativeMatlab.SendMatlabMessage(Native Method)
com.mathworks.jmi.NativeMatlab.sendMatlabMessage(NativeMatlab.java:219)
com.mathworks.jmi.MatlabLooper.sendMatlabMessage(MatlabLooper.java:120)
com.mathworks.jmi.Matlab.mtFeval(Matlab.java:1540)
com.mathworks.mlwidgets.inspector.JidePropertyViewTable.isBeingDeleted(JidePropertyViewTable.java:154)
com.mathworks.mlwidgets.inspector.JidePropertyViewTable.filterOutInvalidObjects(JidePropertyViewTable.java:170)
com.mathworks.mlwidgets.inspector.JidePropertyViewTable.setObjects_MatlabThread(JidePropertyViewTable.java:187)
com.mathworks.mlwidgets.inspector.PropertyView.setObject_MatlabThread(PropertyView.java:655)
com.mathworks.mlwidgets.inspector.PropertyView.setObject_AnyThread(PropertyView.java:591)
com.mathworks.mlwidgets.inspector.PropertyView.access$1300(PropertyView.java:37)
com.mathworks.mlwidgets.inspector.PropertyView$RegistryHandler.itemStateChanged(PropertyView.java:698)
java.awt.AWTEventMulticaster.itemStateChanged(Unknown Source)
com.mathworks.services.ObjectRegistry.fireItemEvent(ObjectRegistry.java:763)
com.mathworks.services.ObjectRegistry.setSelected(ObjectRegistry.java:700)
com.mathworks.services.ObjectRegistry.setSelected(ObjectRegistry.java:617)
com.mathworks.mde.inspector.Inspector.setSelected(Inspector.java:584)
com.mathworks.mde.inspector.Inspector.inspectObjectArray(Inspector.java:569)
com.mathworks.mde.inspector.Inspector.inspectObjectArray(Inspector.java:520)
com.mathworks.mde.inspector.Inspector$11.run(Inspector.java:478)
com.mathworks.jmi.NativeMatlab.dispatchMTRequests(NativeMatlab.java:347)

Workaround:
replace the existing code of SceneViewerListener.m:

>> edit internal.matlab.inspector.SceneViewerListener
...
if ~isvalid(selectedObject)
    beingDeleted = true;
elseif isprop(selectedObject,'BeingDeleted') && strcmp('on',selectedObject.BeingDeleted)
    beingDeleted = true;
elseif ~isempty(ancestor(selectedObject,'figure')) && strcmp('on',get(ancestor(selectedObject,'figure'),'BeingDeleted'))
    beingDeleted = true;
else
    beingDeleted = false;
end

with the following (changed lines are highlighted):

if any(~isobject(selectedObject))
    beingDeleted = false;
elseif ~isValid
    beingDeleted = true;
elseif isprop(selectedObject,'BeingDeleted') && strcmp('on',selectedObject.BeingDeleted)
    beingDeleted = true;
elseif ~isempty(ancestor(selectedObject,'figure')) && strcmp('on',get(ancestor(selectedObject,'figure'),'BeingDeleted'))
    beingDeleted = true;
else
    beingDeleted = false;
end

It looks like this bug was apparently fixed in the R2013b Pre-release without needing to modify SceneViewerListener. But if you still encounter this problem you now know what to do.
I have reported another GUIDE-related bug, but I do not have a workaround for this one: If you run the GUI from within GUIDE, and some uncaught error (exception) occurs, then from that moment onward you cannot save any modifications to the figure file in that session.
Do you know of any other undocumented bugs, preferably with workarounds? If so, please post them in a comment here [6].

Categories: Figure window, GUI, Low risk of breaking in future versions, Stock Matlab function, Undocumented feature


4 Comments (Open | Close)

4 Comments To "A couple of internal Matlab bugs and workarounds"

#1 Comment By Dan On June 12, 2013 @ 18:14

I’m not sure if this is an error or a feature that I’m not comprehending…

I’ve started playing around with using Mask Objects ( [13]) from a Simulink Mask instead of using the old reliable

 MaskValues = get_param(gcb,'MaskValues') 

, etc…
I have a dialog callback that gets that Mask Object. The problem is the Mask Object it gives you gives parameters for the Mask BEFORE it was opened, and does not include changes that you have made to the mask since opening the simulink GUI. (i.e. My dialog callback is working with old data).
My Fix: ??, go back to old reliable.

#2 Comment By Donn Shull On June 15, 2013 @ 09:03

I agree that the disparity between these two values is odd. I might consider it as a feature and explain it as follows.

 
Dialog Values = get_param(gcb,'MaskValues') 

returns the values from the dialog for the mask even if they have not been “applied”

 
BlockMask = Simulink.Mask.get(gcb)
MaskValues = BlockMask.Parameters 

returns the mask parameters that are being used by the block.

#3 Comment By Andrew On June 14, 2013 @ 15:32

I’ve noticed this as well. I find it unhelpful as a developer. It can be useful to know if a bug exists and/or has been fixed in a particular version. This way one can apply workarounds if needed in code used by people who may be running many different versions of Matlab.

For example, Matlab 7.14 (R2012a), 7.13 (R2011b), and probably earlier, has a bug in the inverse complementary error function, erfcinv, where erfcinv(eps(realmin)) returns NaN instead of a finite real value as would be expected and as indicated by the documentation (this occurs in single precision as well). I reported this bug and suggested a simple “workaround.” The bug was acknowledged and I even suggested how it might be fixed when the engineer explained the reason for the underflow. The bug was fixed in Matlab 8.0 (R2012b), but it never showed up in the online database so you’d never know that it exists/existed.

By the way, here is code that will apply a workaround in pre-R2012b versions:

x = erfcinv(y);
if verLessThan('matlab','8.0')
    if isa(p,'double')
        x(y == 2^-1074) = 27.216482834230213;
    else
        x(y == 2^-149) = 10.0198345;
    end
end

Of course verLessThan only goes back to Matlab 7.4 (R2007a), but that’s as far back as I try to retain support…

#4 Pingback By Another couple of Matlab bugs and workarounds | Undocumented Matlab On December 10, 2014 @ 15:56

[…] mind, I don’t take it personally, I simply find a workaround and move on. I’ve already posted about this before. Today I’ll discuss two additional bugs I’ve run across once-too-often, and my […]


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/couple-of-bugs-and-workarounds

URLs in this post:

[1] its share of bugs: http://www.mathworks.com/support/bugreports/

[2] javacomponent function: http://undocumentedmatlab.com/blog/javacomponent/

[3] HG2: http://undocumentedmatlab.com/blog/hg2-update/

[4] enormously helpful: http://blogs.mathworks.com/videos/2013/04/08/using-dbstop-if-error-and-conditional-breakpoints-to-debug-matlab/

[5] this post: http://undocumentedmatlab.com/blog/java-stack-traces-in-matlab/

[6] here: http://undocumentedmatlab.com/blog/couple-of-bugs-and-workarounds/#respond

[7] Another couple of Matlab bugs and workarounds : https://undocumentedmatlab.com/articles/couple-of-matlab-bugs-and-workarounds

[8] Matlab's internal memory representation : https://undocumentedmatlab.com/articles/matlabs-internal-memory-representation

[9] Internal Matlab memory optimizations : https://undocumentedmatlab.com/articles/internal-matlab-memory-optimizations

[10] Accessing internal Java class members : https://undocumentedmatlab.com/articles/accessing-internal-java-class-members

[11] Graphic sizing in Matlab R2015b : https://undocumentedmatlab.com/articles/graphic-sizing-in-matlab-r2015b

[12] Matlab compiler bug and workaround : https://undocumentedmatlab.com/articles/matlab-compiler-bug-and-workaround

[13] : http://www.mathworks.com/help/simulink/slref/simulink.mask.get.html

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.