Debugging in Eclipse

As explained last week, Eclipse groups its different widgets or "views" into "perspectives". The Java perspective is the perspective you'll probably use most frequently. However, there are a couple other Eclipse perspectives that may come in handy.

The Debug perspective allows you to set "breakpoints" in your program. When you then run your program in the debugger, the flow of execution will be suspended at these breakpoints, allowing you to examine the state of your variables before continuing execution.

As a first example, open your HelloWorld class. If you didn't experiment with putting the "System.out.println" in a loop last week, you should do that now. (You can put a breakpoint on the println statement without a loop, but since the program is so simple, it's pretty anticlimactic.)

You insert a breakpoint into a program by double-clicking on the left margin of the editor window next to the line of code where you'd like the debugger to pause your program. So, if you double-click on the margin next to your println statement, you should see a blue circle showing there's a breakpoint there. Then, instead of running your program from one of the regular "Run As" selections, choose "Debug As" and "Java Application". There is a debug icon on the toolbar and some debug options are available under the "Run" menu.

When you tell Eclipse to debug your program, it should switch to the Debug perspective. (If it asks you if that's ok, you can tell it yes.) The Debug perspective opens a few new "views" specific to debugging: the "Debug" view in the upper left corner, which shows a tree view of your execution threads; the "Variables" view to the right of that, which shows any variables your program currently has; and behind the variables view is a "Breakpoints" view, with which you can easily enable/disable all the breakpoints you have set... this saves you the trouble of going back through your code to remove breakpoints that have become distracting to the task at hand.

So, if you run your HelloWorld program in the debugger with a breakpoint on the println statement, the execution should pause at that line. Then, you can use the controls at the top of the debug window to control the flow from there. The green "resume" button will continue program execution until another breakpoint is encountered or the program ends. The square red "terminate" button will kill the program right there. The arrow buttons to the right of there allow you to "step into", "step over", and "step out of" the line at which the debugger is currently stopped. On a more complicated program, "step into" would load the java file for the class with the method called on the current line, allowing you to follow the program execution from class to class. "Step over" allows you to execute the current line without being shown the code and "step out of" allows you to skip to the end of the current method call if you've decided it's not what you need to be looking at.

Try stepping through your program now and then do the following exercise.

Exercise:

Load up the Fibonacci program from the book:

Try putting breakpoints at various places: in the main method, in other methods, in a catch block (and giving it bad data so the exception will be thrown. Be sure to take a look through the variables listings and see their state change as you step through the program.

The objective of this exercise (running the 'inefficient' double recursion fibonacci program) is to see if the debugger helps you understand just how inefficient this design is. count how many times each particular fibonacci calculation is made where n = 6. this should help you understand call stacks, as well.

Some other useful Eclipse tips:

One problem that arises pretty quickly when using the debugger is when you try to follow the flow of execution into classes for which you don't have the source. At this point, Eclipse opens a "class file editor", which isn't really an editor... it just says that it can't find the source and shows a synopsis of the API of that class. However, if you "attach" the souce for the missing class -- which means simply showing Eclipse where to find that source -- it will actually open up the correct source file as you follow the debugger through someone else's code!

Note: it's worth the time attaching the source of any library you use in Eclipse… not just for debugging purposes, but the API tooltip pop-ups show the actual method arg names (instead of arg0, arg1, etc.) and attaching source gives you javadoc popups and something to show in the javadoc view widget.

Eclipse has another way you can "follow" the flow of execution of a program without running it. If you hold down the control key and move the mouse over various identifiers in your code, you'll notice they turn into hyperlinks. Clicking on them takes you to that identifier's declaration (if its source is available). Also, if you hold the control key down and leave the mouse over an identifier for a second or two, a popup window will appear with that identifier's declaration. You can press F2 to give the window "focus", allowing you to scroll through all of that class' code. Clicking on the identifiers to open a new file allows you to follow a potential call trace however.

Following on this thread (bad pun!) a bit more, if you ctrl-click on an identifier in your code you may discover that you've arrived at an interface, and so you're looking at the method signature of the called method without actual implementation code. Well, another useful Eclipse keyboard shortcut is ctrl-t. When you arrived at the interface, the method name you'd clicked on should be highlighted; hitting ctrl-t will open a pop-up that shows the class hierarchy for this method. So, doing this on an interface method name will show you the various implementations of this interface. You can then pick one and view its implementation details for that method.

Exercise: You might now rerun the fibonacci program using these two features.

Along the same lines, ctrl-o in any java file will open a pop-up showing all the methods in that class. And, hitting ctrl-o again while that pop-up is open will add in all superclass methods. This is basically a pop-up version of the "Outline" view that's probably open on the right side of your Java perspective. (And for that matter, the ctrl-t pop-up is the pop-up version of the "Hierarchy" view.)

You can see a list of all the keyboard shortcuts in Eclipse by typing 'ctrl-shift-l'.