You are on page 1of 18

Debugging Techniques

TROUBLESHOOTING COMPUTER PROBLEMS


Testing vs Debugging
Testing a program against a well-chosen set of input tests gives the programmer confidence that
the program is correct. During the testing process, the programmer observes the output that
the program produces for each input test case.
If the program produces the expected output and obeys the specification for each test case,
then the program is successfully tested.
But if the output for one of the test cases is not the one expected, then the program is incorrect
-- it contains errors (or defects, or "bugs"). In such situations, testing only reveals the presence
of errors, but doesn't tell us what the errors are, or how the code needs to be fixed.
In other words, testing reveals the effects (or symptoms) of errors, not the cause of errors.
The programmer must then go through a debugging process, to identify the causes and fix the
errors.
Bug Prevention

As the debugging process often takes longer than the time spent writing the code, the best
technique to avoid bugs in the first place by carefully planning and designing your code.

Having a clean design will reduce the probability of defects in your program.
If a bug does occur a clean design with clear invariants will make it much easier to track down
and fix the bug.
Defensive Programming: Expect the
worst
Defensive programming means developing code such that it works correctly under the worst-
case scenarios from its environment.
For instance, when writing a function, one should assume worst-case inputs to that function,
i.e., inputs that are too large, too small, or inputs that violate some property, condition, or
invariant; the code should deal with these cases, even if the programmer doesn't expect them
to happen under normal circumstances.
Exception Handling?
Examples where we should definitely expect the worst?
Classes of Defect
THERE ARE SEVERAL KINDS OF ERRORS ONE MAY RUN
INTO.
Syntax Errors
These are always caught by the compiler, and reported via error messages.
Typically, an error message clearly indicates the cause of error; for instance, the line number, the
incorrect piece of code, and an explanation.
Such messages usually give enough information about where the problem is and what needs to
be done.
In addition, editors with syntax highlighting can give good indication about such errors even
before compiling the program
Typos and other simple errors
Typos and other simple errors that have pass undetected by the type-checker or the other
checks in the compiler.
Once these are identified, they can easily be fixed.
Here are a few examples: missing parentheses, for instance writing x + y * z instead of (x + y) * z;
typos, for instance passing parameters in incorrect order
Logical Errors
If the algorithm is logically flawed, the programmer must re-think the algorithm.
Fixing such problems is more difficult, especially if the program fails on just a few corner cases.
One has to closely examine the algorithm, and try to come up with an argument why the
algorithm works: rubber ducking.
Trying to construct such an argument of correctness will probably reveal the problem.
.
Debugging Process
The debugging process usually consists of the following:
◦ examine the error symptoms,
◦ identify the cause, and
◦ finally fix the error.

This process may be quite difficult and require a large amount of work for many reasons
Identify The Problem
What did you expect your code to do?
What happened instead?
What is the symptom of the problem?
Under what exact test conditions does the error occur?
What happened before you got the error?
Establish The Cause
After you have identified the issue, you can establish a theory of probable cause.
For example, if your code displays some text, but the text is incorrect, you know that either your
data is bad or the code that set the display text has some kind of bug.
By stepping through the code in a debugger, you can examine each and every change to your
variables to discover exactly when and how incorrect values are assigned
If an exception occurred :-an exception is an unexpected event encountered when running code,
typically an error of some kind. A debugging tool can take you to the exact place in your code
where the exception occurred and can help you investigate possible fixes.
Does the code work on different environments? For example works at home but not in a college
environment. Could it be that a firewall is blocking access to a required resource?
Test probable cause theory to determine
actual cause. ..
Test your hypothesis
Use the debugging tools to ensure your theory worked as expected.
Difficulties with
Debugging
The symptoms may not give clear
indications about the cause
In particular, the cause and the symptom may be remote, either in space (i.e., in the program
code), or in time (i.e., during the execution of the program), or both.
Defensive programming can help reduce the distance between the cause and the effect of an
error.
Symptoms may be difficult to reproduce
Replay is needed to better understand the problem.
Being able to reproduce the same program execution is a standard obstacle in debugging
concurrent programs.
An error may show up only in one particular series of events. And it may be difficult to pin point
how to reproduce that exact same scenario.. 
Bottom-up
Bottom-up debugging the first debugging technique most programmers are taught.
Bottom-up debugging boils bugs down to a cause and effect relationship.
The effect of the bug is often obvious, like sales tax on an accounting application is incorrectly
calculated, but the cause is almost always obscure.
Finding the cause is done by starting to debug the program at a place where it is correct, then
looking at the effect of each method call to determine if it is the culprit.
Bottom-up debugging works well when the effect is well known but the starting point is not
obvious.
Top Down
Top-down debugging focuses on starting with the effect, then working backwards to find
the cause.
This approach to isolate the causes of bugs more quickly than bottom-up but only when the
cause is close to the effect
If code is robust a top down approach is normally quicker.
Divide & Conquer
Explore the code using a divide-and-conquer approach, to quickly pin down the bug.
For example, starting from a large piece of code, place a check halfway through the code.
If the error doesn't show up at that point, it means the bug occurs in the second half; otherwise,
it is in the first half.
Thus, the code that needs inspection has been reduced to half. Repeating the process a few
times will quickly lead to the actual problem. 

You might also like