# Debugging Your Programs Bart Massey [Slides originally from PSU CS 161 Winter 2013 (2013-01-24).] ## What is debugging? * During/after coding, before/during/after testing * Bring the program to a state where it appears to be bug-free (but this is a lie) * Estimate 20-40% of programming effort * "Secret": No good books, no chapter in our book, nothin' ## How to debug * Given a failure of the software: * Find the causes ("faults") leading to that failure * Find the *root causes* of those faults * Figure out and apply a *repair* * Check the repair * Does it fix the failures? * Does it cause new failures? ## Key activity: diagnosis * Like in medicine or car repair: "It doesn't work; what's happening and what can be done?" * Diagnosis is hypothesis formation and testing * What possible reasons *might* there be for observed symptoms? * Can those reasons be ruled out by what is known so far? * If not, can we do tests to rule each reason out or increase our belief that it is the correct one? * Repeat until exactly one possible reason remains, and it looks really likely to be true. ## Common bugs * Two basic kinds: * Bad control flow * Just plain calculating the wrong thing * Examples * Off-by-one "fencepost" errors * Copy-and-paste calculation errors * Typos/"Thinkos" * Failure to design to the spec * Failure to understand/implement the design ## Root Cause Analysis * It's not enough to find the line of code that "causes the bug" * You want to find out how that line got there * In software, faults are caused by mistakes ("errors") that were made by a human (usually you) * With the "root causes" found, you can: * Correct *all* the faults caused by that error * Take steps to make that error less likely in the future ## Preparing code for debugging * "Real programmers don't comment. It was hard to write--it should be hard to read and harder to understand." * Code should have a spec, simple tests, and pseudocode * Formatting should be as clean as possible * Consistent indentation * Consistent liberal use of whitespace * Good names * Idiomatic * Code should be instrumented appropriately ## Debugging pre-inspection * Read the code in question carefully. Look for things that are wrong or unclear * Explain the code to someone. Have them look at it too * Most bugs are easily found and fixed by inspection alone ## Debugging tools: your brain * Are you sure the spec and tests are correct? * White-box: what kinds of similar inputs might produce the same program misbehavior? * Black-box: what properties distinguish misbehaving inputs? * Is the timing as expected? * Are your current hypotheses consistent with *everything* you have observed or can observe? ## Debugging tools: print() function * For a specific hypothesis, stick a print() in that will either disconfirm or confirm the hypothesis * Works in a huge variety of situations * But don't spam instrumentation everywhere, or you will get confused by it * Can use print() for exploring program behavior ("tracing"), but beware: one can waste a lot of time doing this without learning anything. * Always best to know what the question is before you start looking for the answer ## Debugging tools: "debugger" * Idle will happily provide you the ability to * Step through your program one statement at a time * Run until a given program line is reached * Examine/change variable values anytime stopped * Except the debugger is really fragile and hard to use * In particular, doesn't interact well with input() * In general, debugger is tool of last resort ## Post-diagnosis * Once you've found the immediate source of a bug, do RCA * Look for other places where faults may have been inserted due to the same root causes * Think hard about how those faults got there. What are you going to do to avoid this in the future? * Craft fixes that fix the faults properly * This may involve changing the design or revising the specification * Apply the fixes, then test everything carefully * Did the problem get fixed? * Are there new problems? ## Backups, versions and source code management * It is really easy to get the buggy version and the fixed version and the version you are working on right now mixed up * Tool called source code management system helps here * It is probably a mistake to have too many backup files around; in any case, use a consistent clear naming scheme for backup files ## Parting thoughts * Don't get stuck! * Interrupt yourself every few minutes and see if you're making real progress * If you are stuck, many strategies are available: * Try a different approach * Take a break * Ask for help * Don't get discouraged * The most experience programmers still make a lot of bugs and have a hard time fixing them * The bugs you will make are all fixable