Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.

Share this Page URL
Help

Chapter 13: Debugging > What Not To Do - Pg. 183

CHAPTER 13 DEBUGGING while (j < MAX_LEN); { // do stuff here j++; } the semi-colon at the end of the while statement's conditional expression is usually very hard to see, your eyes will just slide right over it; but its effect is to either put the program into an infinite loop, because the loop control variable j is never being incremented, or to never execute the loop, but then erroneously execute the block because it is no longer semantically connected to the while statement. The third type of error, logic errors, are by far the most difficult to find and eradicate. A logic error is one that occurs because you've made a mistake in translating the design into code. These errors include things like computing a result incorrectly, off-by-one errors in loops (which can also be a semantic error if your off-by-one error is because you didn't understand array indexing, for example), misunderstanding a network protocol, returning a value of the wrong type from a method, and so on. With a logic error, either your program seems to execute normally, but you get the wrong answers, or it dies a sudden and horrible death because you've walked off the end of an array, tried to dereference a null pointer, or tried to go off and execute code in the middle of a data area. It's not pretty. Unit testing involves finding the errors in your program, and debugging involves finding the root cause and fixing those errors. Debugging is about finding out why an error occurs in your program. You can look at errors as opportunities to learn more about the program, and about how you work and approach problem solving. Because after all, debugging is a problem solving activity, just as developing a program is problem solving. Look at debugging as an opportunity to learn about yourself and improve your skill set. What Not To Do Just like in any endeavor, particularly problem solving endeavors, there's a wrong way and a right way to approach the task. Here are a few things you shouldn't do as you approach a debugging problem. 1 First of all, don't guess about where the error might be. This implies that (1) you don't know anything about the program you're trying to debug, and (2) you're not going about the job of finding the root cause of the error systematically. Stop, take a deep breath, and start again. Don't fix the symptom, fix the problem. Lots of times you can "fix" a problem by forcing the error to go away by adding code. This is particularly true if the error involves an outlier in a range of values. The temptation here is to special case the outlier by adding code to handle just that case. Don't do it! You haven't fixed the underlying problem here; you've just painted over it. Trust me, there's some other special case out there waiting to break free and squash your program. Study the program, figure out what it's doing at that spot, and fix the problem. You'll thank me later. Avoid denial. It's always tempting to say "the compiler must be wrong" or "the system must be broken" or "Ralph's module is obviously sending me bad data" or "that's impossible" or some such excuse. Buck up here, developer. If you just "changed one thing" and the program breaks, then guess who probably just injected an error into the program? Or at the very least uncovered one? Review the quote from Sophocles at the beginning of this chapter, "... you yourself and no one else has made it." You will make mistakes. We all do. The best attitude to display is, "by golly, this program can't beat me, I'm going to fix this thing!" One of the best discussions of careful coding and how hard it is to write correct 1 McConnell, S. Code Complete 2: A Practical Handbook of Software Construction. (Redmond, WA: Microsoft Press, 2004). 183