The code executes up to the breakpoint and stops; the line of code where execution is
The Debug perspective is worth examining in depth. You can see entries for the programs you're debugging in the Debug view at the upper left. Note, in particular, the stack frames here, marked with three horizontal bars. In this case, we can see we're in the
factorial
method, which has been called by the
main
method. The three buttons next to the word Debug in the Debug view are (from left to right) the Resume (start executing code again), Suspend (pause code, as when you've got a runaway infinite loop), and Terminate (stop debugging)
To the right of the Debug view is a set of
The Breakpoints view lets you manage the breakpoints in your code by right-clicking a breakpoint in the list and selecting items like Disable, Enable, Remove, or Remove All from the context menu. The Expressions view lets you evaluate expressions, as we'll see in a few pages. When you select an expression in the editor, right-click it, and select Inspectit'll be evaluated in the Expressions view. Similarly, when you select the Display item from the context menu, the results will appear in the Display view.
The editor under the Debug perspective is
Next to the editor is the Outline view at the lower right (also seen in Figure 3-11), which is the same as in the Java perspective. Below the editor is the Console view, which displays program output just as in the Java perspective.
3.2.3 Stepping Through Code
The most fundamental way to move through paused code is by
For example, our debugging session is currently paused at the line return value * factorial(value - 1) . Pressing F5 single-steps into that line, which means we begin executing the factorial(value - 1) call, as you can see in Figure 3-12, where the new value in the value variable is 5. Figure 3-12. Single-stepping
So far, we can see that the factorial method is progressing as it should. When it was first invoked, value was 6. In this second call to factorial , value is 5.
You can also use
step filters
to indicate what code you want to filter out while single-stepping. When you filter out the code in a class or package, that code is not stepped into when you use the Step With Filters option, which is great if you want to avoid stepping through system code. To set step filters, you use Window
Figure 3-13. Setting step filters
We could keep single-stepping through our code to try to find the problem with that code. Or we could use the breakpoint we've already set to make things move faster. 3.2.4 Resuming Execution Until Encountering a Breakpoint
We've been single-stepping through our code, and we can continue doing that, but we'd have to keep going through each line of iteration of the
factorial
method, which can be a little
Before doing that, however, we can also set up the Debug perspective to watch the value in our value variable. That way, Eclipse will automatically display the value in that variable, making life a little easier. To watch the value in the value variable, just right-click that variable in the editor and select the Watch item. Doing so will add value to the Expressions view. Now click the Resume button; when you do, execution resumes until a breakpoint is encountered, as you see in Figure 3-14. You can see that we're still in the same call to factorial by taking a look at the value of the value variable, which is 5. This is apparent because we're watching it in the Expressions view at the upper right. Figure 3-14. Running to a breakpoint
Now all we need to do is keep resuming execution by clicking the Resume button through all the iterations of factorial . But there's an even easier way still! 3.2.5 Setting Breakpoint Hit CountsThere are supposed to be six iterations of the factorial method, so we'd have to hit the Resume button six times. That's not too bad, but you can also configure breakpoints in Eclipse with hit counts . When you use a hit count of n , the breakpoint won't be triggered until the n th time it's encountered, which can save you time. To set a breakpoint's hit count, right-click the breakpoint in the Breakpoints view and select the Properties item, opening the Java Line Breakpoint Properties dialog you see in Figure 3-15. In this case, select the Enable Hit Count checkbox and enter 6 as the hit count. Then click OK to close this dialog. Figure 3-15. Setting a breakpoint hit count
Now restart the debugging session (end the session by clicking the Terminate button or using the Run
Figure 3-16. Using a breakpoint's hit count
To examine any of the stack frames in the Debug view, and the values of local variables in them, just double-click a frame to make it the active frame. The factorial example generates plenty of stack framesjust double-click one and you'll see that all the local variables like value have been preserved frame-by-frame. In the current stack frame, value = 1, in the next frame under this one, value = 2, and so on.
We've been able to skip to the final iteration of the
factorial
method just by setting our breakpoint's hit count, and everything still looks fine. We should be able to comfortably single-step to the end of the code at this point. However, when you click the Step Into button, execution unexpectedly enters the
factorial
method once again, and in the Expressions view you can see that
value
is set to 0, which is a problem because it should never be set to 0; factorials only work with positive whole
Figure 3-17. Discovering the error
Looking at our code (note the highlighted line in Figure 3-17) reveals the problemwe keep the iterations going until value is set to 0 instead of stopping at 1:
public static int factorial(int value) {
if(value == 0){
return value;
}
else {
return value * factorial(value - 1);
}
}
We fix the problem like this:
public static int factorial(int value) {
if(value == 1){
return value;
}
else {
return value * factorial(value - 1);
}
}
You can see the new,
Figure 3-18. The fixed program
And that's all it takeswe've debugged the code. This example gave us a start with debugging, but there's much more available in the JDT. 3.2.6 Configuring BreakpointsWe've used a breakpoint hit count to make life easier. Besides using hit counts, you can configure standard breakpoints in several other ways as well; to do that, right-click a breakpoint, bringing up the Breakpoint Properties dialog shown in Figure 3-19. If you select the Enable Condition checkbox, you can enter a condition in the Condition box that will cause the breakpoint to suspend the program. For example, you might be having problems every time a variable named inventory is set to 0; in that case, you might use the condition inventory == and select the "condition is `true'" checkbox. 3.2.6.1 Checking a condition
You can also break when the value of a condition changesfor example, if some part of your code is changing the value in a variable named
ipAddress
and it shouldn't, you can type that variable
3.2.6.2 Multithreaded debuggingYou can also handle multithreaded debugging hereyou can list the threads you want to restrict a breakpoint to with the Restrict to Selected Thread(s) box, and you can also set the suspending policy to either Suspend Thread (the default, which still allows other threads in the application to continue) or Suspend VM (which suspends the entire virtual machine that Eclipse has launched and connected to in order to debug your code). Figure 3-19. Breakpoint properties
3.2.6.3 WatchpointsThe standard breakpoints we've been using are called line breakpoints , and besides line breakpoints, the JDT supports other types of breakpointsfield ( watchpoints ), method, and exception.
Field breakpoints, also called watchpoints, suspend execution when your code is going to access and/or modify the value of a field. Watchpoints may not be set on local variables (such as those you declare inside
To set a watchpoint, select a field in a Java view and select Run
Figure 3-20. Configuring a watchpoint
3.2.6.4 Method breakpoints
Method breakpoints suspend execution when you enter or leave a method, depending on how you configure them, and you usually use these breakpoints on methods you don't have the source code for. To set a method breakpoint, highlight the call to that method in a Java view and select the Run
Figure 3-21. Configuring a method breakpoint
3.2.6.5 Exception breakpointsYou can also work with exception breakpoints, which let you suspend execution when an exception happens. This is very useful if your code throws an exception, such as a null pointer exception, and you don't know where that exception is happening. You can suspend execution and see what's going on with your code when a thrown exception is caught (or not caught).
To set an exception breakpoint, select Run
Figure 3-22. Configuring an exception breakpoint
You can configure the properties for an exception breakpoint as you can for any other breakpoint; just right-click the breakpoint in the Breakpoints view and select the Properties menu item. For example, you can see how we're configuring a breakpoint for uncaught java.lang.NullPointerException exceptions in Figure 3-23. You can restrict the breakpoint to specific locations, and even use hit counts, but you can't specify any conditions for this breakpoint as you can with line breakpoints. Figure 3-23. Configuring a Java exception breakpoint
3.2.7 Evaluating Java Expressions and Changing ValuesWhile you're debugging, you can enter expressions into the detail pane of the Expressions view (the detail pane is just above the lower horizontal scrollbar in the Expressions view), selecting the expression, right-clicking it, and selecting the Inspect menu item. For example, if the variable value holds 6, you can enter the expression value + 1 in the detail pane, right-click it, and select the Inspect item. Doing that adds value + 1 to the list of expressions in the Expressions view and displays the value of that expression, 7, in the detail pane, as you see in Figure 3-24. Figure 3-24. Evaluating an expression
And, as mentioned earlier, you can also edit the values of fields and variables while debugging your codejust double-click a field or variable name in the Variables view, opening the dialog you see in Figure 3-25. In this case, we've double-clicked the variable named value in the Variables view; to change the value in this variable at runtime, just enter a new value and click OK. It's great if you want to check the impact on your code of different test valuesfor example, to check what happens if you set a variable named denominator to 0or if you want to avoid known problem values. Figure 3-25. Editing a variable's value
3.2.8 Using Hot Code ReplacementYou can even edit your code as you're debugging using the JDT debugger, as long as you're working with a JRE that supports it. This is called hot code replacement , and it requires a JRE Version 1.4 or later.
The
Now you're free to edit your code during a debugging session. After you've changed the code, save it and resume execution (if you haven't enabled
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %} For example, we can edit our factorial code while debugging (as you see in the highlighted line in Figure 3-26), by changing this line in the factorial method:
public static int factorial(int value) {
if(value == 1){
return value;
}
else {
return value * factorial(value - 1);
}
}
The new line is shown here:
public static int factorial(int value) {
if(value == 1){
return value;
}
else {
return 2 * value * factorial(value - 1);
}
}
Then just save the code if you have auto-build turned on. That's all it takesnow you've
Figure 3-26. Using hot code
|