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 (AFAIK), no chapter in normal programming books, 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.

Diagnosis: gathering evidence

  • Observation: what do you see?

    • What is being printed at compile time? At runtime?
    • What is timing like? Unexpected pauses? Unexpectedly fast?
    • What side effects on the system do you observe?
  • Analysis: what do you know?

    • How should the system work?
    • What kinds of bugs should be expected?
  • Most bugs can be diagnosed without "extra" experiments: "psychic debugging"

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"

  • A modern debugger 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 I/O and the like

  • In general, debugger is tool of last resort

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

Repair

  • 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?

Post-repair

  • Propagate: 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?

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

  • Source code management system is mandatory; avoid "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

Last modified: Wednesday, 24 February 2021, 2:28 PM