Debugging a Program

Very few of us are so lucky that we write a piece of code that works right away. Sometimes it will be nothing but a few compile errors blocking you. In less fortunate circumstances, you'll find yourself with a program that compiles and runs, but does nothing close to what it's supposed to. You can guess at what might be going on, or you can throw in a ton of println() calls, but neither of these works particularly well with complex programs.

Often, the best way to approach a serious bug or malfunction is to walk through your program line by line, looking at what the values of your variables are and which lines of code get executed at what points. You can simulate this by hand, but it's often arduous and error-prone. Luckily, modern IDEs make this very easy by integrating automatic debugging capabilities.

Breakpoints

The main debugging mechanism in most IDEs, including Eclipse, is the "breakpoint." All a breakpoint represents is a line of code at which the program will stop executing normally and will instead allow you, the user, to step through what follows, line by line, examining variables and watching control flow. To create a breakpoint in a Java file inside Eclipse, all you need to do is double-click in the grey space immediately next to a line number on any line. It really makes no sense to put breakpoints on certain lines, like variable or method declarations. Instead, put them on non-declarative statements.

before double-click

Text editor view prior to setting a breakpoint

after double-clicking line #22

Text editor view after setting a breakpoint on line #22

Running in debug mode

Once you've set one or more breakpoints (you can set as many as you like), you will want to run your program in debug mode. Rather than clicking the "play" button at the top of the screen as you normally would, you'll want to click the little beetle/bug-like button immediately to its left.

The 'Run in debug mode' button

Your program will now execute as it normally would, though you may find that Eclipse switches (or asks you to switch) to the Debug perspective. This perspective is just a handy collection of views that will help you debug (things like the Variables, Debug, and Breakpoints views).

The Debug perspective

As soon as your program hits one of your breakpoints, it will pause, giving you control. Whenever it's paused like this, you can use the Variables view to take a look at the current values of any variable and its sub-fields. In the text editor itself, an arrow will appear at the left side of the line which is next to be executed. At first, it will be the line you put the breakpoint on.

Debugger displays the next line of code to be executed
The Variables view allows you to see the content of variables

In addition, you can check the values of any variable or even complete expressions by mousing-over them in the text editor, or by highlighting full statements and then right-clicking on them and clicking on "Inspect." For instance, to see what the evaluation of the expression textField.getText() in the code below, I highlight it, right-click, choose "Inspect," and then get the following results (i.e. the String "15"):

Inspecting the value of an expression

Controlling control flow

Debugging control flow buttons

When executing pauses after hitting a breakpoint, you have control of how execution proceeds. There are a number of buttons (pictured above) which allow you to move through the code that follows in the most convenient way. The most important are these: