Monday, May 4, 2009

Debugging - A way to locate and fix code

During development, one of the basic lessons that I learnt was "DO NOT USE debug print statements like 'debug.print' or 'System.out.println' to locate a problem in the code. It is time consuming and not effective." The process of locating bugs is one of the hardest tasks a developer will face. It is, however, an essential part of the debugging process.The key to repairing a bug is to isolate the problem to a particular system component and to then locate the exact section at fault. In small systems, it may be easy to spot where a problem lies, but in larger systems that are composed of dozens or hundreds of classes, it isn't quite so easy. Tracking which class and which method is responsible can be a frustrating task.

Working with code written by other developers can be especially difficult, because you don't have the intuitive familiarity that you would with code that you've written yourself. The problem can often be very hard to locate, particularly if one component of a system is interacting badly with another, such as modifying public member variables or passing bad data to methods. This often masks the problem, making a developer think that one class is at fault when in reality it is another. Worse still, certain types of Java software present unique challenges. Applets, for example, are notoriously unstable on certain browser configurations, and network restrictions such as a firewall between users and the Internet may make it difficult to replicate bugs within a developer's intranet. Networking code can cause headaches, as it is often hard to tell whether the client, the server, or both are at fault. Servlets have no graphical user interface or user console, so seeing what is going on behind the scenes is very tricky. Multi-threaded code that works fine at some times may exhibit a bug at other times. Software that relies on other components, such as distributed services like RMI servers or CORBA servants, often is not fault-tolerant and reacts badly (and sometimes mysteriously) if the other components fail. Most of these problems can be alleviated by two popular debugging techniques: logging and tracing.

Logging should not be used for development debugging (but it inevitably gets used that way by logger.info or debug.pring or system.out.print). Logging should be designed for operational monitoring and trouble-shooting. Tracing should be designed for development debugging & performance tuning. If available in the field, it can be use for really low-level operational trouble-shooting, but that is not its main purpose. Given this, the most successful approaches I've seen (and designed/implemented) in the past do not combine the two together. Better to keep the two tools separate, each doing one job as well as possible.

Using a debugger makes finding this information quite simple.Debugging is a powerful technique that allows you to observe the run-time behavior of your program and determine the location of semantic errors. Many of the IDE like Visual Studio, Eclipse, JBuilder etc come with a built-in debugger that provides all standard debugging functionality, including the ability to perform step execution, to set breakpoints and values, to inspect variables and values, and to suspend and resume threads. Additionally, you can debug applications that are running on a remote machine. With the debugger, you can do the following:Set breakpointsConditional breakpointsEvaluating ExpressionsViewing / Editing VariablesRemote Debugging.

I also feel debugging is a good way of learning about the functionality in the code. You can de-bug me if you have any questions...:)

No comments:

Post a Comment