A Debugging session that you wish you could wake up from. Here are some remedies to help you think outside the box: * Mental exhaustion will make you forget obvious things, and concentration will keep them out of your brain. ''Think about something else.'' Go away and sleep, party, or eat. For 20 seconds, or 20 hours. When you get back the answer will be sitting there waiting for you. * Write a ProgrammerTest. * Single-step through everything, putting watches on any variables that could possibly be relevant. * Write a ProgrammerTest. * Binary chop the entire program in half. Then debug the half with the bug. Then chop again. If you could see where the bug wasn't, you would have found it by now. * Write a ProgrammerTest. * Rebuild everything from scratch, top-down, adding one function at a time. * Write a ProgrammerTest. * Port everything to another 'puter, and try its environment. * Write a ProgrammerTest. * Roll the code back to the last working version, and add the new features again. * Write a ProgrammerTest. * Total rebuild the source. You could have a compiler or linker glitch. * Write a ProgrammerTest. * Immediately go to sleep, without taking a break, nibbling, or watching TV. This kind of sleep pattern tends to cause an "anxiety dream" - a lucid nightmare that cleanses your hormones. You might even have a BenzeneDiscovery experience: http://encyclopedia.thefreedictionary.com/benzene%20ring * Write a ProgrammerTest. * Google for similar problems, particularly if using third-party libraries. * Write a ProgrammerTest. * Pin down everything that works >right< with assertions. * Write a ProgrammerTest. * Take out all your extra cruft and trace statements - you could have "debugitis" - bugs caused by excess debugging. * Write a ProgrammerTest. * Look through the source code of any libraries and third-party tools you're using. * Write a ProgrammerTest. * Refactor something at random. * Write a ProgrammerTest. * Ask your customer if you can nuke the scope the bug lives in. * Write a ProgrammerTest. The bonus is that when you've finished you will have some ProgrammerTest''''''s, and/or refactored code. ''Brilliant ZenSlap/GentleSarcasm. Nicely done.'' ---- In addition to writing the tests, as suggested above, one needs to believe the tests. If the tests show that the area your are concentrating on is working, believe them and look else where. There are times refactoring reveals latent errors in surrounding code; just because the error appeared when you made a change, does not always imply the change caused the error. The vast majority of the time, an error can be traced back to the most recent change, so start looking there. If however, you have refactored once, fallen back to the old code, refactored a second time, and the error still pops out, try looking at the surrounding code for the problem. ----------- I encountered a problem that escaped testing for the oddest reasons. I borrowed a date validation routine from the web that used the JavaScript "parseInt" function. I tested boundary conditions for month numbers such as 1, 12, and 13. However, months 8 and 9 sometimes didn't work because if you put a zero in front of the number ("08"), then parseInt assumes it is octal unless one explicitly gives it a second parameter indicating base. Thus, "12" works fine because it is not interpreted as octal because it does not start with a zero. Further, in some of my tests I didn't bother typing in a leading zero. Thus a date of "1/8/2005" would pass the test. ''Since that problem happens to everyone, '''eventually''', I wouldn't call it "for the oddest reasons", I would say that that's actually an excellent example of how well-intentioned tests can run afoul of mental blocks.'' To veer this discussion in a slightly different direction, I would suggest that this is a prime example of a method screaming to be refactored; it is doing too much (Yeah, I know changing this is outside of our realm of feasibility, but it is a good example of the principle). It would have been much better to just create two methods, parseInt and parseOctalInt and allow the programmer to explicitly choose the function desired rather than try to make an implicit decision base on a data format. The point of this is not that there is anything one can do to prevent these types of mistakes based on external code, but that one should avoid this type of thing in code under one's range of control. ''Well, the lesson to learn is to specify the base explicitly using "parseInt('08', 10)" instead of simply "parseInt('08')". This is an example of not using the library correctly (as well as an object lesson in JavaScript's poor ApiDesign).'' JavaScript authors picked a stupid default behavior and should be slapped. Octal is probably like 0.001% of number usage in the field. I'd like to see their reasoning steps as an object lesson in how NOT to think when designing languages or general API's. Let's investigate the mental plane crash. ---- See Also: DreadedDayOfDebugging, BigBangTesting, HeisenBug