Java stack traces in Matlab

When debugging Java events in Matlab callbacks, it is sometimes useful to check the stack trace of the originating Java code. Matlab’s built-in dbstack function only reports the stack-trace of Matlab code, and any prior Java code in the stack trace is not reported. Knowing this information is also extremely important when debugging Java components that are used in Matlab, especially when using the Java-to-Matlab Interface (JMI).

Let’s use a specific example to illustrate: Matlab’s uitable passes information back and forth between its underlying Java code and Matlab, via the arrayviewfunc Matlab function (%matlabroot%/toolbox/matlab/codetools/arrayviewfunc.m). If we place a breakpoint in arrayviewfunc and then update the table’s data, dbstack will only report the Matlab stack:

% Prepare an empty uitable
>> hTable = uitable('ColumnName',{'a','b','c'});
 
% Place a breakpoint in arrayviewfunc
>> dbstop in arrayviewfunc at reportValuesCallback
>> dbstatus
Breakpoint for arrayviewfunc>reportValuesCallback is on line 588.
 
% Update the table data and wait for the breakpoint to trigger
>> set(hTable,'Data',magic(3));
 
% Check the Matlab stack trace – no sign of the invoking Java code
K>> dbstack
> In arrayviewfunc>reportValuesCallback at 588
  In arrayviewfunc at 42

To see the originating Java stack trace, we can use java.lang.Thread‘s static dumpStack() method, which spills the Java stack trace onto the stderr console (will appear in red in Matlab’s Command Window):

K>> java.lang.Thread.dumpStack
java.lang.Exception: Stack trace
   at java.lang.Thread.dumpStack(Unknown Source)
   at com.mathworks.jmi.NativeMatlab.SendMatlabMessage(Native Method)
   at com.mathworks.jmi.NativeMatlab.sendMatlabMessage(NativeMatlab.java:219)
   at com.mathworks.jmi.MatlabLooper.sendMatlabMessage(MatlabLooper.java:121)
   at com.mathworks.jmi.Matlab.mtFeval(Matlab.java:1550)
   at com.mathworks.hg.peer.ui.table.DefaultUIStyleTableModel$UITableValueTableModel$1.runOnMatlabThread(DefaultUIStyleTableModel.java:467)
   at com.mathworks.jmi.MatlabWorker$2.run(MatlabWorker.java:79)
   at com.mathworks.jmi.NativeMatlab.dispatchMTRequests(NativeMatlab.java:364)

To access and possibly parse the originating Java stack trace, we can use the following trick:

K>> st = java.lang.Thread.currentThread.getStackTrace;
K>> 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:121)
com.mathworks.jmi.Matlab.mtFeval(Matlab.java:1550)
com.mathworks.hg.peer.ui.table.DefaultUIStyleTableModel$UITableValueTableModel$1.runOnMatlabThread(DefaultUIStyleTableModel.java:467)
com.mathworks.jmi.MatlabWorker$2.run(MatlabWorker.java:79)
com.mathworks.jmi.NativeMatlab.dispatchMTRequests(NativeMatlab.java:364)

Each of the stack trace elements can be inspected, to get specific properties:

K>> st(1).getFileName
ans =
     []		% empty = unknown
 
K>> st(2).get
	Class = [ (1 by 1) java.lang.Class array]
	ClassName = com.mathworks.jmi.NativeMatlab
	FileName = NativeMatlab.java
	LineNumber = [-2]
	MethodName = SendMatlabMessage
	NativeMethod = on
 
K>> st(2).isNativeMethod
ans =
     1		% 1 = true
 
K>> char(st(2).getFileName)  % cast java.lang.String to a Matlab char
ans =
NativeMatlab.java
 
K>> st(2).getLineNumber
ans =
    -2		% negative = unknown
 
K>> st(5).get
	Class = [ (1 by 1) java.lang.Class array]
	ClassName = com.mathworks.jmi.Matlab
	FileName = Matlab.java
	LineNumber = [1550]
	MethodName = mtFeval
	NativeMethod = off

This works well in JVM 1.5 (i.e., Matlab 7.04 or R14 SP2) and higher. In older Matlab releases you can use a slight modification:

K>> t = java.lang.Throwable; st=t.getStackTrace;
K>> for idx = 1 : length(st), disp(st(idx)); end
com.mathworks.jmi.NativeMatlab.SendMatlabMessage(Native Method)
... (etc.)
Categories: Java, Low risk of breaking in future versions

Tags: ,

Bookmark and SharePrint Print

4 Responses to Java stack traces in Matlab

  1. Laurent says:

    Hello Yair,

    Do you know if there a way to avoid displaying the java stack trace that may appear (some kind of “warning off all” but for java exceptions)?

    I have a tree in one of my GUI and it sometimes returns exceptions. This does not prevent the correct execution but my users don’t like red messages they don’t understand and I would like to hide those traces.

    Thx
    Laurent

    • @Laurent – I too would love to disable these warnings (actually, these are Java exceptions, but in many cases as you said they act as mere warnings that do not affect code execution). Unfortunately I do not know of any way to suppress them.

    • Laurent says:

      so bad…
      Thank you for your quick reply and for everything you share with us.

      Laurent

  2. Pingback: A couple of internal Matlab bugs and workarounds | Undocumented Matlab

Leave a Reply

Your email address will not be published. Required fields are marked *