MATLAB Community

MATLAB, community & more

Adding Debugging Code Without Changing Your Code


I’d like to welcome guest blogger Ken Atwell from the MATLAB Technical Marketing team. Ken will occasionally be blogging here on the Ken & Mike on the MATLAB Desktop blog.

As helpful as facilities like breakpoints and MATLAB’s interactive environment are, I’m sure that many of us still use “old school” debugging techniques from time to time. Chief among these is scattering disp statements throughout your code and then combing through the output to try to spot where something has gone awry. It is ad hoc for sure, but it gets the job done.

This comes with an obvious downside, though, namely that you will later need to remove all of the debugging code. Not an impossible task, especially if you have a baseline under source control to “diff” against, but it’s an error-prone step nevertheless. One of the more embarrassing moments in my professional career was when I left a debugging statement in the production code. Overnight, the regression test engine unceremoniously barfed on the nightly build and I came into the office the next day to a chorus of jeers. All in good fun and little harm done, but that prompted me to look for alternatives.

Enter the conditional breakpoint, a seemingly unlikely ally. If you have not used conditional breakpoints to date, I encourage you to experiment with them. They are very useful when you need to run through a breakpoint many times before your application gets into (or approaches) an error state.

The trick to using a conditional breakpoint is to simply appreciate that the condition will always be evaluated, but the breakpoint will only be triggered if the condition evaluates to some non-zero value. The condition can be “x>0”, or “min(x{:})>0”, or even … drum roll …“fprintf(‘x is %d\n’, x)”. Basically, it can be any expression that evaluates to some value. Unfortunately, this means we cannot (directly) use disp, since disp does not return a value. That is, you’ll get an error if you try to do something like “y=disp(x)”.

So, let’s try using an “un-conditional” breakpoint to display a string. Set a breakpoint inside your favorite piece of code. Then, right-click that breakpoint and choose “Set/Modify Condition”.

Make the condition “fprintf(‘Hello, World!\n’)”. Now run that code and you’ll see “Hello, World!” written to the Command Window. We did this without modifying the source code itself, so we don’t need to remember to back the change out later. The conditional breakpoint is also shown in yellow in the Desktop, distinguishing it nicely from normal (red) breakpoints.

Right about now you are probably saying, “but my program stopped running at that breakpoint, I wanted my program to continue!” Now we need to concern ourselves with the conditional itself. doc fprintf will remind us that the length of the string is returned. In our case, this was 14 (on my Windows box). This is not zero, so the debugger stopped execution. We need to augment our condition to always evaluate to false. Something like “0==fprintf(‘Hello, World!\n’)” will do the trick. Here, the value returned by fprintf, 14, will be compared against zero (0). The values are not equal, so this expression evaluates to logical false (zero). This means the debugger will continue to run the program.

Make this change to your conditional breakpoint and rerun your program. It still displays the message we inserted, but the program now runs through the breakpoint as desired.

Wait…but what if you are printing something that might actually be of length zero, meaning 0==0, meaning logical true, meaning my program stops-when-I-don’t-want-it-to? Actually, this can’t happen here because the ‘\n’ (newline) guarantees at least one character of output. But, if you don’t have such a guarantee in your fprintf, you can guard against the zero length case with the following funny-looking expression, which always evaluates to false:

0 == fprintf(something) && 0

The “&& 0” performs a logical AND to zero, guaranteeing a false (0) evaluation overall, meaning the debugger will never break at this breakpoint.

Using techniques like this, one can temporarily and non-destructively inject nearly any behavior into their application.

If you’ve ever used conditional breakpoints in an unconventional way, be it in MATLAB or other applications, we’d love to hear about it and learn from your experience and creativity.


-by Ken Atwell, The MathWorks

|
  • print

评论

要发表评论,请点击 此处 登录到您的 MathWorks 帐户或创建一个新帐户。