Like testing, debugging isn't a way to improve the quality of your software; it's a way to diagnose defects.
Effective approach for finding a defect:
1. Stabilize the error.
2. Locate the source of the error.
a. Gather the data that produces the defect.
b. Analyze the data that has been gathered and form a hypothesis about the defect.
c. Determine how to prove or disprove the hypothesis, either by testing the program or by examining the code.
d. Prove or disprove the hypothesis using the procedure identified in 2(c).
3. Fix the defect.
4. Test the fix.
5. Look for similar errors.
Tips for finding defects:
1. Use all the data available to make your hypothesis. When creating a hypothesis about the source of a defect, account for as much of the data as you can in your hypothesis
2. Refine the test cases that produce the error. If you can't find the source of an error, try to refine the test cases further than you already have.
3. Exercise the code in your unit test suite. Defects tend to be easier to find in small fragments of code than in large integrated programs.
4. Reproduce the error several different ways. Sometimes trying cases that are similar to the error-producing case, but not exactly the same, is instructive.
5. Generate more data to generate more hypotheses. Choose test cases that are different from the test cases you already know to be erroneous or correct.
6. Use the results of negative tests. Suppose you create a hypothesis and run a test case to prove it. Suppose the test case disprove the hypothesis, so that you still don't know the source of the error. You still know something you didn't before, that the defect is not in the area in which you thought it was.
7. Brainstorm for possible hypotheses. Rather than limiting yourself to the first hypothesis you think of, try to come up with serveral.
8. Narrow the suspicious region of the code. If you've been testing the whole program, or a whole class or routine, test a smaller part instead.
9. Be suspicious of classes and routines that have had defects before. Classes that have had defects before are likely to continue to have defects.
10. Check code that's changed recently. If you have a new error that's hard to diagnose, it's ususlly related to code that's changed recently.
11. Expand the suspicious region of the code.
12. Integrate incrementally. Debugging is easy if you add pieces to a system one at a time.
13. Check for common defects. Use code-quality checklists to stimulate your thinking about possible defects.
14. Talk to someone else about the problem. Some people call this "confessional debugging." You often discover your own defect in the act of explaining it to another person.
15. Take a break from the problem. Sometimes you concentrate so hard you can't think.
Fixning a defect
1. Understand the problem before you fix it. The best way to make your life difficult and corrode the quality of your program is to fix problems without really understanding them.
2. Understand the program, not just the problem. If you understand the context in which a problem occurs, you're more likely to solve the problem completely rather than only one aspect of it.
3. Confirm the defect diagnosis. Before you rush to fix a defect, make sure that you've diagnosed the problem correctly.
5. Save the origianl source code. You should fix the symptom too, but the focus should be on fixing the underlying problem rather than wrapping it in programming duct tape.
6. Change the code only for good reason.
7. Make one change at a time.
8. check your fix. Check the program yourself, have someone else check it for you, or walk through it with someone else.
9. Look for similar defects. When you find one defect, look for others that are similar.