Suggestion #5: Debugging with Undo
By Tor Norbye on Sep 27, 2005
Until now in this "column" I've written about source code itself: Don't use vanity tokens, don't capitalize acronyms, don't use tabs, and don't (over)use logging. Today I'd like to talk process instead: debugging.
The process of debugging usually involves mental verification: you step through the code, and compare what you think should be happening with what is actually happening. As you do this, you frequently have to decide if you should Step Into or Step Over method calls. On the one hand, you don't want to step over a method in case the bug is occurring within the method call. On the other hand, if you don't know where the bug is yet, you can waste a lot of time stepping through methods before the bug is triggered.
With the following technique however you get the best of both worlds. The approach is as follows: Always step over. If you detect that the bug has happened (e.g. some return value from a method is wrong, or a class field is changed into the bad value you're looking for, etc. etc.) then simply Retry the method. By retry, I mean pop the current stack frame and step back into the method! This gives you a primitive "Undo" function. Without restarting your program, you get to step through the method again.
Many debuggers offer actions to pop the stack, so you can use this technique today. What I really want however is a convenient action which does both of these operations (pop followed by step into), and have it located in a convenient place such as the debugging toolbar.
So I decided to try out the new NetBeans 5.0 module plugin development support. Holy cow! - It was unbelievably easy! In 25 minutes, I wrote a plugin (which adds a debugger toolbar action which pops the stack and steps into in one step), I generated a plugin bundle, installed it in the IDE and tested that it works on a simple test program. And this was as a first time user of the plugin support! I especially liked the "New | Action" wizard which automatically handled everything from icon and displayname to positioning the action in the menus and toolbars.
I'm not exaggerating - it took just 25 minutes. And I'm not bragging either; doing all this in 25 minutes says something about the productivity of the tool, not about my programming skills. There's a quick-start document available with more information on how to build plugins in 5.0. But I wrote the plugin while on the train commuting to work, and without a network connection I figured it out anyway on my own.
The screenshot on the right (click for full size) shows the IDE in action; notice the new action in the toolbar (easily spottable by the ugly icon I supplied) as well as the plugin project in the navigator.
Anyway, you can use this retry technique as long as your IDE supports Pop Topmost Stackframe. It sometimes requires a little work on your part. If you're stepping through a method that has side effects (such as initializing fields), you may have to account for these. By "account for" I mean undo the side effect. Usually I handle it by clearing out the fields in the watch window after popping the stack. You did realize you can change values in the Value column and cause assignment in the debugged process, right?