Loren on the Art of MATLAB

Turn ideas into MATLAB

Note

Loren on the Art of MATLAB has been archived and will not be updated.

Stop If

Today's guest post comes from Sean de Wolski, one of my fellow Application Engineers. You might recognize him from MATLAB answers and the pick of the week blog!

Have you ever wanted MATLAB to pause in debug mode when a certain condition is met? Perhaps when a specific problem-file out of a directory is read or on an iteration of a for-loop that yields an unexpected result? Perhaps that for-loop has to iterate a few dozen or hundred times before the problem iteration occurs and you don't want to walk through step by step in debug mode?

In this post, we're going to survey a few different ways to handle this.

Contents

Keyboard

I was talking with a MATLAB user recently about the merits of the keyboard function of which I'm not a big fan. Keyboard pulls you into debug mode as soon as it's encountered. They claimed to like it for difficult debugging when certain criteria are met.

Here's a simple example scenario. CM is the cameraman image:

imshow(CM)

This is a simple algorithm to show how many pixels are brighter than each pixel value in the uint8 range of [0 255].

xg = zeros(1, 256);
for ii = 0:255
    xg(ii+1) = sum(CM(:)>ii);
end

plot(0:255, xg)
ylabel('Pixels Greater Than X')
axis tight

Somewhere around iteration 125 appears to be giving me problems; I'd expect the curve to be positive through to 255.

I want to see what's happening on iteration 125 and the subsequent ones. One way would be to put a break point on the calculation line, hit run, and then hit the continue button 125 times hoping I don't get in a rhythm and accidentally skip it. This has some obvious shortcomings in that it doesn't scale and is time consuming.

The approach with keyboard would look like this:

xg = zeros(1, 256);
for ii = 0:255
    if ii == 125
        keyboard
    end
end

Now on the 125th iteration, we enter the if-statement and can step in debug mode into the problem area. This is pretty straight-forward and is a safe, decent solution. However, it requires changing the code in order to debug it and will require changing it again once we've fixed the bug.

DBSTOP ...

What if we could just stop if? Well you can! dbstop, the function underlying breakpoints, supports a wide range of conditional breakpoints.

These breakpoints can be set from the breakpoints menu on the editor tab or with dbstop directly. Here's the same code encapsulated in a function called badForLoop.

function badForLoop(CM)
xg = zeros(1, 256);
for ii = 0:255
    xg(ii+1) = sum(CM(:)>ii); 
end

plot(0:255, xg)
ylabel('Pixels Greater Than X')
axis tight
end

To set it from the breakpoints menu, select "Set Condition" while the cursor is on the line you'd like to stop on.

Then enter your condition; any valid MATLAB code will work here.

To set the same breakpoint programmatically:

dbstop in badForLoop at 4 if (ii==125)
badForLoop(CM);

Testing and Clean Up

If you think you have a fix, you can then disable the breakpoint without clearing it by either clicking on the yellow breakpoint itself (an X will appear over it indicating it's disabled). If the problem is resolved, clicking the breakpoint again will clear it or you can reenable it by right clicking. This can be done from the menu as well and clearing can be done with dbclear.

The analogous workflow with keyboard would be to highlight the selection and comment it out to "disable" and then delete to clear.

The fix for this toy problem was that the image was stored as an int8 with a range [-128 127] rather than a uint8 with range [0 255].

Bonus

Additionally, dbstop has some predefined conditions to stop on including on errors, warnings, or if nans or infs are encountered. If you haven't discovered dbstop if error yet, I strongly suggest giving it a try. When an error occurs, it stops and you can view the state of the world as it was when the error occurred.

Comments

Do you have any debugging war stories where one of these tricks could've helped? What about other uses for the keyboard command? Let us know here.




Published with MATLAB® R2017a


  • print