How to debug a program
First thing is first. Make sure you have done each of the following
before spending time in the debugging phase.
-
Do you have a complete strategy for solving the problem?
Did you work out the possible complications and special cases
your program might run into? Use paper and pencil for this phase
and try running your program idea through several examples on paper.
-
Plan out helper methods. Helper methods are always a good idea
because they are
- reusable
- separately testable and debuggable
- make the overall program logic easier to follow
-
Write logically detailed pseudocode that executes your strategy
from step 1. Be detailed in exactly how things will work, but do it in English
instead of code. The syntax details don't matter, but the logical details do.
Once you have logically detailed pseudocode, writing your program will simply mean
turning the pseudocode into comment lines and then writing the equivalent Java
instructions below the comments. Each of your helper methods also needs its
own pseudocode.
Now you are ready for the debugging phase - which will be much easier now that you
have a detailed idea of how your program will work.
Debugging Suggestions
Determine whether you have a compiler error, runtime error, or logic error.
Compiler errors
Something is syntactically wrong with your program code.
The Java compiler will tell you what the problem is. You need to understand
what it's telling you. If you don't understand the message, look here:
http://www.skylit.com/javamethods/JM-Appendix-B.html
http://mindprod.com/jgloss/compileerrormessages.html
Runtime errors
Your program is syntactically correct, but it allowed something illegal
to happen when it ran. Here's an example:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at Paw.claws(Paw.java:39)
at Cat.scratch(Cat.java:209)
at Animals.main(Animals.java:55)
You should read these errors from bottom to top. They say which line crashed
and provide you with the chain reaction leading back to the cause.
Reading from bottom to top, line 55 in the main()
method of
Animals.java
crashed because line 209 in the scratch method
Cat.java
crashed. But that crashed because line 39 in the claws
method of Paw.java
crashed...which crashed because of an
ArrayIndexOutOfBoundsException: -1
So, that's the problem.
Line 39 in the Paw class tried accessing an array index of -1,
which is illegal because arrays go from 0 to length-1. You need to debug
your code and figure out why -1 is being calculated as the array index.
Here are explanations of common runtime error messages:
http://mindprod.com/jgloss/runerrormessages.html
Logic errors
Your program compiles and runs but it doesn't produce the output desired.
- Isolate the problem.
Comment out everything. Then uncomment as few lines as necessary
to make your program compile and run. Once that's working, uncomment
a few more lines and make sure they work by recompiling and running your
program. Make sure the variables and output up to that point are correct.
You should add println()
statements to verify the values of variables up to
that point in your program.
- Test methods separately with known inputs.
Well-written programs are broken into parts using separate methods and
separate classes. Test each part separately. For example, if my
program needs to find the fifth word in a sentence then I might have
a separate method for it:
String findNthWord(String s, int n) // finds the nth word in String s
// code not shown
}
I can test to see whether this part of my program works properly on
its own. In the main()
method, I can run some tests:
// This should produce an error message
System.out.println( findNthWord("Hello there, how are you?", 0) );
// This should print "Hello"
System.out.println( findNthWord("Hello there, how are you?", 1) );
// This should print "there,"
System.out.println( findNthWord("Hello there, how are you?", 2) );
// This should print "you?"
System.out.println( findNthWord("Hello there, how are you?", 5) );
// This should produce an error message
System.out.println( findNthWord("Hello there, how are you?", 6) );
- Recognize that many of the logical errors students make in programs
is failing to recognize special cases. In other words, you wrote
code that is misbehaving in a way you didn't expect because you
didn't think of handling special cases. When planning your
program you must think through all the scenarios of what could be
inputted into your methods/program. You need a plan that addresses
all the reasonable possibilities. As with many things in life,
you will often find out the special cases for the first time during
the debugging process.
- Add lots of
System.out.println()
statements to your program to trace
the value of variables during runtime. Find out why it's doing what
it's doing.
- Use a debugger that allows you to "watch variables" and "step" through
your program running it line by line. The free version of JCreator
doesn't do this. BlueJ does and so do many other IDEs. You can also
use standalone debuggers such as JSwat.
Debuggers are very handy tools for stepping through code.