How to tell what subfunction ran last in a GUI? For debugging.

I am testing a complex GUI written by someone else. If I push certain buttons in sequence a bug appears: instead of plotting a recently-loaded image, an old image is plotted. It's hard to tell what part of the program causes the bug: each button calls several functions, and there are many imshow calls. To pinpoint which imshow command retrieves the outdated image, is there a way to tell what function or line of code last ran, perhaps from the command line?
[Since I don't know where in the code the problem occurs, breakpoints are cumbersome because I'd have to put them into all the functions, plus I find it hard to 'step out' of debugging which I believe is a known issue with GUIs in R2015b.]

7 Comments

It would probably be quicker to do some old-fashioned debugging and just put a quick
disp( 'Something or other' )
call after each of the imshows, obviously something different and meaningful for each.
I'm not aware of anything that can give you the last function called if you are not in a breakpoint and all functions have completed.
If you are actually in code then
doc dbstack
can help with this, though it won't go back through previous callback calls.
Good to know. I have to admit I broke down and put a break point after each of the 20+ imshow calls and used comments to keep track of the one which caused the outdated image to reappear. In general I am finding it hard to track the logic flow through a GUI compared to 'regular' code. I'll bet more experienced GUI programmers than me have tricks to deal with this.
Well, there are well designed GUIs and badly designed GUIs like all other code. A good design will have minimal code in the GUIDE file itself, but this tends to involve using a class-based approach if the GUI is complicated. This is what I usually do though it is easy to fall into quick sloppiness and just put a load of code in the GUI file itself for a 'quick' GUI.
OK, that makes sense: it is hard to debug this program because everything is in one mfile. I will look around online for examples of a good complicated GUI + support mfiles. I may buy 'Learning to Program with MATLAB: Building GUI Tools' as well.
If you learn Matlab OOP and are familiar with OOP generally it is so much easier. You barely need to care about the fact there is a GUI there because all your callbacks simply delegate straight to a class that does the work in just the same way it would if run from command line or some other non-GUI function. That way the GUI is just as light-weight a front end as possible, doing nothing beyond getting inputs from the user and passing them on to a program.
I'm sure it can be done with function-based programming as well and structs and all that, but I'd rather give up programming altogether than do that!
I don't know why it would be harder to debug if all your functions are in the same file. Actually I find it easier. If you had 30 functions that you were editing, then you'd have 30 editor windows open instead of one. Since they won't all show up, if you want to go to one, you have to use that little down arrow on the tab strip. So if you want to go to a function you can either type control-D if your cursor is in the function to go to its definition, which would either be in the same file or in a different file. OR you can search for it - in the same file you'd use control-f but if you had separate files for each function you'd need to use control-shift-f. Personally if I am not planning on using those functions in any other file, I put them inside the only file where they will ever be used. If a function will be used by many other programs, like a useful utility function, then I have it in its own file in my "Utilities" folder.
For novices like me looking for an example of OOP control of a GUI, here are some I found:

Sign in to comment.

 Accepted Answer

Yes, you can tell from the call stack. One way to do it is to simply put a fprintf() as the first line of every function saying what is executing. But if you want stuff shown/printed only when there is an error, you can look at the call stack. Wrap the contents of all your functions in a try/catch block:
% Sample usage
try
% Some code that might throw an error......
catch ME
callStackString = GetCallStack(ME);
errorMessage = sprintf('Error in program %s.\nTraceback (most recent at top):\n%s\nError Message:\n%s', ...
mfilename, callStackString, ME.message);
WarnUser(errorMessage);
end
The function GetCallStack() is attached below.

More Answers (0)

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Asked:

KAE
on 27 Jun 2017

Commented:

KAE
on 5 Jul 2017

Community Treasure Hunt

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

Start Hunting!