Undocumented Matlab
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT

Better MEX error messages

February 24, 2016 2 Comments

I would like to introduce guest blogger Pavel Holoborodko, the developer of the Advanpix Multiprecision Computing Toolbox for MATLAB. Pavel has already posted here in the past as a guest blogger about undocumented Matlab MEX functions. Today he will discuss another little-known aspect of advanced MEX programming with Matlab.
MEX API provides two functions for proper handling of erroneous situations: the legacy mexErrMsgTxt and the newer mexErrMsgIdAndTxt. Both show error message, interrupt execution of a MEX module and return control to Matlab immediately.
Under the hood, these functions are implemented through C++ exceptions. The reason for this design choice is unclear. Throwing C++ exceptions across module boundary (e.g. from dynamic library to host process) is unsafe and generally considered as bad practice in software design. Exceptions are part of C++ run-time library and different versions of it might have incompatible implementations.
This restricts MEX to use only the same version of C++ run-time and GCC which were used to build that particular version of Matlab itself. This is one of the reasons why TMW distributes its own version of GCC/libstdc++ along with every release of Matlab and pushes developers to use it for MEX compilation.
Such unfortunate design decision have two unpleasant consequences:

  1. developers must use some old version of GCC (forget all the fancy stuff from C++11, C++14, etc.)
  2. compiled MEX modules most likely will not work on older/newer versions of MATLAB (re-compilation is required).

The good news is that both issues are solvable and I will write more about this in the future (it is actually possible to create single binary MEX module, which will work on any GNU Linux flavor regardless of the versions of libc/libstc++/gcc installed in the system or used in Matlab).
Here I propose just first step towards freedom – avoid direct usage of mexErrMsg** functions. Use a simple wrapper instead:

void mxShowCriticalErrorMessage(const char *msg)
{
    mxArray *arg;
    arg = mxCreateString(msg);
    mexCallMATLAB(0,0,1,&arg,"error");
}

void mxShowCriticalErrorMessage(const char *msg) { mxArray *arg; arg = mxCreateString(msg); mexCallMATLAB(0,0,1,&arg,"error"); }


The mxShowCriticalErrorMessage function calls Matlab’s built-in error function via the interpreter, with the error message as input parameter.
In addition to being safe, this approach potentially gives us better control over what additional information is shown together with error messages. Instead of a string, we can use an errorStruct as input argument to Matlab’s error function, with its fields tuned to our requirements (not shown here as I want to keep the example simple).
Even without tuning, output of mxShowCriticalErrorMessage is much more informative and user-friendly:

  • Error message from Matlab’s built-in functionality:

    >> A = magic(3);
    >> A(0)
    Subscript indices must either be real positive integers or logicals.

    Nice one-line message without any distracting information.
     

  • Error message from MEX using mexErrMsgTxt/mexErrMsgIdAndTxt:

    >> A = mp(magic(3));   % convert matrix to arbitrary precision type, provided by our toolbox
    >> A(0)                % subsref is called from toolbox, it is implemented in mpimpl.mex
    Error using mpimpl
    Subscript indices must either be real positive integers or logicals.
    Error in mp/subsref (line 860)
            [varargout{1:nargout}] = mpimpl(170, varargin{:});

    Intimidating four lines with actual error message lost in the middle. All the additional information is meaningless for end-user and actually misleading.
    The worst thing is that such error message is very different from what user get used to (see above one-liner), which leads to confusion if MEX plugin is properly working at all.
     

  • Error message from MEX using mxShowCriticalErrorMessage:

    >> A = magic(3);
    >> A(0)
    Error using mp/subsref (line 860)
    Subscript indices must either be real positive integers or logicals.

    Now the message is clear and short, with error description in the last line where the user focus is.
     

Related posts:

  1. Checking status of warning messages in MEX – Undocumented Mex functions can be used to extract the state of Matlab warnings in run-time. ...
  2. Setting system tray popup messages – System-tray icons and messages can be programmatically set and controlled from within Matlab, using new functionality available since R2007b....
  3. Sending email/text messages from Matlab – Sending emails and SMS (text) messages from Matlab is easy, once you know a few quirks....
  4. Matlab compilation quirks – take 2 – A few hard-to-trace quirks with Matlab compiler outputs are explained. ...
  5. Parsing mlint (Code Analyzer) output – The Matlab Code Analyzer (mlint) has a lot of undocumented functionality just waiting to be used. ...
  6. Faster csvwrite/dlmwrite – The speed of the builtin csvwrite, dlmwrite functions can be improved dramatically. ...
Mex Pavel Holoborodko Undocumented feature
Print Print
« Previous
Next »
2 Responses
  1. Yaroslav February 25, 2016 at 20:17 Reply

    A very interesting post. Is this problem persists for compiling MEX with c or Fortran, or is there another behaviour altogether?

    • Pavel Holoborodko February 26, 2016 at 13:42 Reply

      I guess it will come down to compatibility of setjmp/longjmp used in LIBC, that you compile your MEX against.
      (C++ exceptions are implemented through these low-level functions with all the additional things for calling class destructors, etc.)

      Cannot say about Fortran though – but probably the situation is similar there.

Leave a Reply
HTML tags such as <b> or <i> are accepted.
Wrap code fragments inside <pre lang="matlab"> tags, like this:
<pre lang="matlab">
a = magic(3);
disp(sum(a))
</pre>
I reserve the right to edit/delete comments (read the site policies).
Not all comments will be answered. You can always email me (altmany at gmail) for private consulting.

Click here to cancel reply.

Useful links
  •  Email Yair Altman
  •  Subscribe to new posts (email)
  •  Subscribe to new posts (feed)
  •  Subscribe to new posts (reader)
  •  Subscribe to comments (feed)
 
Accelerating MATLAB Performance book
Recent Posts

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

Categories
  • Desktop (45)
  • Figure window (59)
  • Guest bloggers (65)
  • GUI (165)
  • Handle graphics (84)
  • Hidden property (42)
  • Icons (15)
  • Java (174)
  • Listeners (22)
  • Memory (16)
  • Mex (13)
  • Presumed future risk (394)
    • High risk of breaking in future versions (100)
    • Low risk of breaking in future versions (160)
    • Medium risk of breaking in future versions (136)
  • Public presentation (6)
  • Semi-documented feature (10)
  • Semi-documented function (35)
  • Stock Matlab function (140)
  • Toolbox (10)
  • UI controls (52)
  • Uncategorized (13)
  • Undocumented feature (217)
  • Undocumented function (37)
Tags
ActiveX (6) AppDesigner (9) Callbacks (31) Compiler (10) Desktop (38) Donn Shull (10) Editor (8) Figure (19) FindJObj (27) GUI (141) GUIDE (8) Handle graphics (78) HG2 (34) Hidden property (51) HTML (26) Icons (9) Internal component (39) Java (178) JavaFrame (20) JIDE (19) JMI (8) Listener (17) Malcolm Lidierth (8) MCOS (11) Memory (13) Menubar (9) Mex (14) Optical illusion (11) Performance (78) Profiler (9) Pure Matlab (187) schema (7) schema.class (8) schema.prop (18) Semi-documented feature (6) Semi-documented function (33) Toolbar (14) Toolstrip (13) uicontrol (37) uifigure (8) UIInspect (12) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
  • Marcel (11 days 10 hours ago): Hi, I am trying to set the legend to Static, but this command seems not to work in R2022a anymore: set(gca,’LegendColorbarL isteners’,[]); Any ideas? THANKS / marcel
  • Gres (11 days 14 hours ago): In 2018b, you can get the icons by calling [hh,icons,plots,txt] = legend({‘Line 1’});
  • Yair Altman (13 days 9 hours ago): @Mitchell – in most cases the user wants a single string identifier for the computer, that uniquely identifies it with a distinct fingerprint that is different from any...
  • Mitchell (13 days 17 hours ago): Great post! I’m not very familiar with the network interfaces being referenced here, but it seems like the java-based cross-platform method concatenates all network...
  • Yair Altman (16 days 11 hours ago): Dani – You can use jViewport.setViewPosition(java .awt.Point(0,0)) as I showed in earlier comments here
  • dani (17 days 6 hours ago): hi!! how i can set the horizontal scrollbar to the leftside when appearing! now it set to right side of text
  • Yair Altman (26 days 3 hours ago): Dom – call drawnow *just before* you set hLine.MarkerHandle.FaceColorTy pe to 'truecoloralpha'. Also, you made a typo in your code: it’s truecoloralpha, not...
  • Dom (27 days 2 hours ago): Yair I have tried your code with trucoloralpha and the markers do not appear transparent in R2021b, same as for Oliver.
  • Yair Altman (30 days 9 hours ago): Ren – This is usually the expected behavior, which avoids unnecessary duplications of the Excel process in CPU/memory. If you want to kill the process you can always run...
  • Yair Altman (30 days 23 hours ago): When you use plot() without hold(‘on’), each new plot() clears the axes and draws a new line, so your second plot() of p2 caused the first plot() line (p1) to be...
  • Cesim Dumlu (37 days 6 hours ago): Hello. I am trying to do a gradient plot for multiple functions to be displayed on the same axes and each one is colorcoded by respective colordata, using the same scaling. The...
  • Yair Altman (45 days 9 hours ago): @Veronica – you are using the new version of uitree, which uses HTML-based uifigures, and my post was about the Java-based uitree which uses legacy Matlab figures. For...
  • Veronica Taurino (45 days 9 hours ago): >> [txt1,txt2] ans = ‘abrakadabra’
  • Veronica Taurino (45 days 10 hours ago): Hello, I am just trying to change the uitree node name as you suggested: txt1 = 'abra'; txt2 = 'kadabra'; node.setName([txt1,txt2]); >> "Unrecognized method, property, or...
  • Yair Altman (48 days 10 hours ago): The version of JGraph that you downloaded uses a newer version of Java (11) than the one that Matlab supports (8). You need to either (1) find an earlier version of JGraph that...
Contact us
Undocumented Matlab © 2009 - Yair Altman
This website and Octahedron Ltd. are not affiliated with The MathWorks Inc.; MATLAB® is a registered trademark of The MathWorks Inc.
Scroll to top