When You Reach Your Break(ing) Point. . . Or Not
May 10, 2016 Susan Gantner
I’m always surprised at how well-attended my RDi debugging presentations are. After all, once you know about service entry points, there’s not a huge amount that’s new and radically different about debugging, even with RDi. Then again, I’m constantly learning new things. Here’s something I learned just last week, in fact.
Let’s assume that you already have a debug session running on the troublesome program and we’ll look at setting and using breakpoints. The most obvious and common way to set one is to position your cursor on the statement where you want it. From there, you can use “Add/Remove Breakpoint” from the context menu or double click the mouse to the left of the SEU-style statement number. One way you won’t be able to set a breakpoint is by using the old green-screen debugger function key (F6) because in RDi, F6 performs a “step” action.
Once you have one or more breakpoints set, they will show up in the source with the breakpoint symbol to the left of the statement number. They will also show up in the Breakpoints view, which is one of the tabbed views in the upper right corner of the default Debug perspective, as shown in the figure below. Interacting with breakpoints from this view is often easier than finding them in the source. For example, double clicking on one of the breakpoints here will position the source view to that statement, which is a good thing since you’ve probably noticed that the line number shown in the breakpoints doesn’t match the source sequence numbers, just like the line numbers in the cross-reference in the Outline view.
Notice the check box before each breakpoint in this view. By unchecking these, you can temporarily disable the associated breakpoint without having to delete it altogether. If you want to disable all the breakpoints at once, rather than unchecking all the boxes, there’s a “Skip all breakpoints” icon. This is the feature that I recently learned about when trying to figure out why someone’s debug session wasn’t stopping at any breakpoints. This switch had accidentally been turned on. This could come in handy at some point if you have lots of breakpoints set and you realize that you need to re-start the program during a debug session and you want it to be able to finish the current run normally. Just don’t forget to turn it back off again or none of your breakpoints will work!
That brings me to one of my favorite features of RDi breakpoints: the fact that they hang around even after a debug session has ended. This has helped me on many occasions when I’ve had trouble replicating a particular problem in debug or I’ve just failed to find the bug before it was time to give up and vow to try attack the bug later. At least I don’t have to remember where all those breakpoints were so I can re-set them in subsequent debug sessions. Of course, there’s a flip side to everything. It also means that I must remember to remove the breakpoints at some point or they will hang around forever. That’s made fairly easy, though, by the “Remove All Breakpoints” icon (the two X’s) in the breakpoint view.
Suppose you want to make a breakpoint conditional. For instance, you only want it to stop when X > 399. We could do this in the green screen debugger; surely we can in RDi. Simply set the breakpoint normally and then edit it from the context menu on the breakpoint, either in the source view or in the breakpoint view. In the resulting dialog, click on the Next button to find the “Expression” box, where you can put a simple expression to control the behavior of your breakpoint. The only other thing I’ve ever used the edit breakpoint dialog for is to add a “user label” for the breakpoint. In the figure you can see that I’ve added a user label to one of my breakpoints just to help me remember what’s happening at that point in the program. When you have a large program with many, many breakpoints in it, it sometimes comes in handy to know at a glance the significance of the breakpoint location.
If you use watch breakpoints in the green screen debugger, or even if you didn’t, perhaps because you didn’t know they existed, they can also be done in RDi. A watch breakpoint is different from a line breakpoint (the type we’ve talked about so far) in that it is not associated with a particular line of code. Instead it is associated with a variable. If you don’t know where a problem occurs in the logic, but you know that it has something to do with a strange value appearing in variable X, you can tell the debugger to “watch” variable X and stop the program execution whenever the value of X changes so that you can poke around to figure out how you got there.
In RDi, I normally double click on the variable name in the source to select it, then choose “Add Watch Breakpoint” from its context menu. Don’t be concerned about the fact that the resulting dialog shows “0” for the number of bytes to watch. To me, that always sounds like it’s not going to watch anything, but in debugger-ese apparently “0” means “all”, so it will monitor for any change in any byte in that variable. Whenever the variable changes in the debug session, the program will stop and a message will pop up to alert you. At that point you could simply hover your cursor over the variable name to see its current (newly changed) value. Watch breakpoints show up in your breakpoints view along with your line breakpoints and can also be temporarily disabled from there. This is helpful when you’re going through a loop that changes that value and you are confident the problem isn’t in the loop. Rather than continually stopping each time through the loop, you can disable the watch breakpoint and set a line breakpoint shortly just after the end of the loop, or use the next type of breakpoint described below. Watch breakpoints can also be set via the context menu in the breakpoints view.
One more breakpoint type that I use with RDi is what I call a temporary breakpoint. From the context menu on a line of code during a debug session, you have the option to “Run to Location.” While this isn’t a breakpoint in the sense that it appears in your breakpoints view, I consider it a temporary breakpoint in that it causes the program to stop running on that line but with the advantage that you don’t need to remember to remove the breakpoint after you get there.
I hope you have learned something about breakpoints. In another tip, I’ll cover a few more of my favorite things about the RDi debugger.
Susan Gantner is half of Partner400, a consulting company focused on education on modern programming and database techniques and tools on the IBM i platform. She is also a founding partner in System i Developer, a consortium of System i educators and hosts of the RPG & DB2 Summit conferences. Susan was a programmer for corporations in Atlanta, Georgia, before joining IBM. During her IBM career, she worked in both the Rochester and Toronto labs, providing technical support and education for application developers. Susan left IBM in 1999 to devote more time to teaching and consulting. Together with Jon Paris, she now runs Partner400, and appears regularly at many technical conferences, including System i Developer’s RPG & DB2 Summit. Send your questions or comments for Susan to Ted Holt via the IT Jungle Contact page.