Like any other major software package, Matlab too has its share of bugs. 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 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:
- Keep the handles of all the relevant Java components, and then delete them directly:
- Use findobj to delete all components, rather than the clf function (we use setdiff to prevent deletion of the figure window itself):
Note that this bug does not occur when using HG2. 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 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
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 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)
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.