Debuggers are back in the spotlight with a recent post from Kasia. She likes debuggers, so do I.
No matter how productive you are with your current tools, I guarantee you will be more productive with an IDE and with a debugger.
I am pretty good with emacs and vi, with pinpointing potential bug areas by just reading code or quickly reading reams of output on a console, but at the end of the day, I just get things done faster if I add my IDE and a debugger to my arsenal of tools. Ignoring this simple common sense is like being a caveman saying that he’s okay without fire.
The point of this entry is not to revive this debate (let’s leave cavemen into their caves) but to ponder the following question: why is there almost no information on how to use a debugger wisely? I don’t mean the user manual telling you how to set a breakpoint and how to single-step through code. I mean a "good practice" guide.
As far as I know, this is not taught in school and hardly broached in books and I wonder why. Is it because debuggers vary widely in scope and functionalities?
I don’t believe this statement is true any more: these days, debuggers have converged toward a very similar set of functionalities and except for a few innovations such as back-in-time debugging, you can reasonably expect your debugger to offer the same functions, regardless of the language or the operating system you are debugging in.
I would love to see a central place where all debugger tips and practices can be found, I’m sure there is a wealth of information waiting to be uncovered out there.
I’ll start with a few tips of my own.
Run method till it exits
Sometimes, you accidentally step into a method you didn’t mean to investigate, typically a library method. You want to "get out" of this method so you can resume the debugging of the method you are really interested in. You do this in Eclipse with the Step return button:
Press it and the current method will be run until it exits and the current frame is popped, taking you back to where the call was made.
Using conditional breakpoints.
I cannot overstate how important conditional breakpoints are. Unless you are working on a very simple piece of code, the bug you are trying to find or the code you are trying to test will probably not be exercised right away, or it will be run several times without the parameters you are expecting. The only way to get there faster is to type in entire expressions in your conditional breakpoint text box.
Using break conditions for println
As I stated in the link above, I’m not a big fan of "println debugging", which is antiquated and actually quite dangerous at times. That being said, a bug sometimes happens after a certain number of iterations which cannot be easily captured by a conditional breakpoint (see below). Or maybe, you just want to have some information about the state of the program displayed on stdout so that when you hit your breakpoint, the console contains some context information.
How could you do this without inserting println’s in your code?
Simple : use a breakpoint expression that will do this println for you.
For example, the expression above could simple be replaced with "System.out.println(methodName)". Since this expression will never return true, the program will never stop, but it will display the value of methodName throughout the entire execution.
Now, that’s what I call an efficient use of println and since the logic is contained in the debugger and not your code, no risk of shipping with it.
Of course, you don’t have to limit this to just println, you could just as easily modify existing variables or do some other crazy stuff…
How about you? Any hot tips to share about your relationship with your debugger?