Copyright Chris Johnson, 1998.
Human Computer Interface Design Using Java

Chris
DEBUGGING
by

Chris Johnson



Before we begin...

The first thing is DON'T PANIC! Breathe deeply, relax your neck muscles and smile... Every programmer in the world has produced code with bugs in it. The trick is not only to identify and correct those bugs but also to understand WHY they arose in the first place. This brief introduction to debugging is intended to help you understand the causes of these problems. I am also assuming that your programming environment does not provide a sophisticated debugging facility. If it does then steps five and six can be supplemented by the step and trace facilites that these systems support.

If your program doesn't behave as expected then there are a number of steps that you can take to resolve the problem. The most important thing is to try to identify the source of the error BEFORE you go ahead and start hacking the code any further. If you try to get the program to work by changing things in an unplanned manner then you'll make it worse. Not only will you not understand the cause of the problem but you may then not be able to work out how your code "evolved" though unplanned changes.


Step one: make a copy of your program.

You should get into the habit of saving copies of your code as you go along. This gives you a reference point to go back to if you encounter bugs at any stage. However, you may find problems in getting the code to run in the first place. One way of avoiding this is to minimise the amount of code that you write before you attempt to run it. For example, it is possible in AWT to construct parts of the graphical structure before you develop the event handlers/listeners that implement the behaviour of the interface. Get one thing working before you try to build the next and make sure that you keep a "clean" copy of that first stage.


Step two: establish a working hypothesis

If you've hit a bug then there may be several reasons for the failure. If your code will not compile then you will need to check the AWT documentation to check that the methods and classes that you reference are valid. The AWT API (application programmer interface) contains this documentation.


Step three: Check the APIs

If your program will compile but still does not behave as intended then you need to figure out the reasons for the problem. At this stage there may be one or two obvious things to try. For example, if a Component does not appear on the screen then you may have forgotten to show() it or it may have a size of (0,0) or it may have been postioned off the screen itself. Alternatively, if a Component does not respond to an input event then you may not have written an approrpiate listener method for its class. Before altering your code, you should satisfy yourself that your hypothesis would account for the behaviour that you observe.

Hint: at this stage, I usually try to get a friend to check things. If I can convince them that my hypothesis is correct only then will I fgo ahead and re-write the code.


Step four: simplify the program or write a test rig

Very often people introduce several new features into a program before they stop to test it. As mentioned above, this leads to situations in which several different hypotheses might be used to explain the apparent behaviour of the system. In order to clarify things, it is often a good idea to strip out some of these additional features until you get back to the root cause of the problem that you have introduced. If you save your later version then you can easily re-introduce the new features once the bug is fixed.

Sometimes, the behaviour of a program is so complex that it makes more sense to write a small program simply to test out your hypothesis. These programs can be used in the documentation for your final product - they are evidence of testing. This simplification process helps to ensure that you understand the cause of your problem rather than becoming obsessed by the various symptoms that you observe by hacking away at the full implementation.


Step five: use DEBUG statements

Debug statements simply print out information that can be used to trace the causes of a problem. They are intended for programmers, they are not intended for the user of an application. It, therefore, follows that they should be switched on during development but MUST be turned off in the final product. A simple means of achieving this is through the use of boolean constants that can be set to true if the statements are to be printed or false if they are not to be shown. For example, a very crude form of DEBUG statement might be implemented as follows if(DEBUG==true) System.out.println("Got to here..."); Remember that in some browsers you will have to explicitly select the Java Console in order to view this output (Hint: it's usually under the options menu).

Please leave debug statements in your programs - if someone else wants to use your code after you have finished then they can help them to understand the way that your program works.


Step six: if all else fails

Go home, get some sleep, do something different. Programming involves intense cognitive effort. It can be an extreme form of problem solving activity so you will need rest. Often after a break, intractable problems can suddenly seem obvious. Please, however, do not try to solve problems by ignoring them. Set a time to go back and look one more time at the bug.

If you really cant get you program to work then ask your friends, demonstrators or tutor for help. This is valid even in assessed exercises, providing that you acknowledge the help in a comment beside the code - after all they may introduce further bugs and it is good practice to provide a reference to the author of each part of your program.

Finally, if your program does not work as intended the you MUST state this in the documentation. You must also provide an account of any tests that you have conducted to explore the problem as well as a brief description of the final working hypothesis that might explain the source of the bug. This will help anyone who fllows after you to improve upon your code and possibly remove the problem.