Cpts224logo

Home

Syllabus

Notes

Homework

Grades


Debugging -- Tools and Techniques


Debugging -- Tools and Techniques
        Bugs
        Good Clues, Easy Bugs
        No Clues, Hard Bugs
        Debuggers
        When all else fails
        Other people's bugs


Reading:  Chapter 5: Debugging

Note: in the assert macro example, and the debug flags and TRACE examples we will see soon, NDEBUG is typically set in the Makefile as part of the CFLAGS variable.

Bugs

  • Debugging is hard
  • Good coding can reduce bugs
  • No one has yet figured out how to prevent bugs

Good Clues, Easy Bugs

  • Many (most?) bugs are pretty straightforward
    • Some simple deduction can get you a long way
      • What did I expect?
      • What happened instead?
      • How far did the program get?
      • Did everything look ok up until that point?
    • The book says you're trying to figure out how something impossible happened.
      • Of course, it's more that something theoretically impossible happened
  • Look for familiar patterns
    • Languages tend to have their own common bugs
      • The text gives a couple of examples in C
      • Another "good one" in C (and Perl) is
        • if ( i = 7 )
    • The compiler can catch a lot of bugs, but there are some that will never be seen until runtime
  • Examine the most recent change
    • It is highly likely that your last change either caused the bug or triggered it elsewhere in the code
    • diff can be a handy debugging tool
      • What's different between a working version and a non-working version?
      • Many source control systems have some means available to compare versions
        • RCS has rcsdiff
        • CVS has cvs diff
  • Don't make the same mistake twice
    • If you find a bug, check the rest of the program for the same bug
      • We tend to do things wrong in consistent ways
  • Debug it now, not later
    • If you find a bug, fix it
      • Human nature is not to "get back to it"
    • Mars Pathfinder example
      • The Pathfinder computers had to be reset about every day
        • Due to a known bug that was on the "do it later" list
        • A bit harder to fix a few million miles away
  • Get a stack trace
    • A stack trace will show you exactly where the program was when it failed
    • Can help you "work back" to the root cause
    • You might also be able to examine the values of variables at the time of death
  • Read before typing
    • Before "fixing" anything, think it through
    • Diving in to fix a bug often causes more bugs
  • Explain the code to someone else
    • Even if they don't understand you, in explaining it, you can often see the problem
  • Turn on (or add) debugging output
    • Maybe just seeing what's going on will show you what you need to see
    • Even better, build in debugging that you can turn off, like the debug flags and TRACE macro systems we will cover

No Clues, Hard Bugs

  • Alas, there are bugs that offer (seemingly) no clues
    • The problem appears to be random
  • Make the bug reproducible
    • "Always" and "never" are much easier to figure out than "sometimes"
    • The first thing to do is to try to make the bug reproducible
      • i.e. Find a condition that makes it an "always" or "never" symptom
    • This may give you the answer, but if not, it at least gives you a test to run against any possible solutions
  • Draw a picture
    • Sometimes a histogram or other chart of your data may point out flaws that are otherwise non-obvious
  • Use tools
    • Use diff to compare versions of a program, or successful vs. unsuccessful output
    • Use shell scripts to automate your testing
    • Use grep or vi to examine output
    • Use tail -f to watch log files in real time
    • Write simple programs to test hypotheses
  • Keep records
    • Take good notes on what you're trying
    • For reference, remembering what you've done, and knowing what you don't need to try
    • Legend has it that after a thousand or so failed attempts at making an electric light, Thomas Edison said he was making progress because he now knew 1000 ways not to make an electric light. Debugging can be like that.
  • For big programs with long lifetimes, develop a validation suite.

Debuggers

  • When a bug is really insidious, an interactive debugger can be a huge help
  • Often the problem is that you think one thing and the program is doing another
    • This type of "mental bug" is almost impossible to find, since you'll always "think right past it"
  • Debuggers allow you to step through a program, or to set "breakpoints"
    • You can watch your program run
    • Often at some point, you'll think, "Wait! It's not supposed to do that!"
      • Bingo!
  • Perl has a handy built-in debugger, which we'll cover when we talk about perl.
  • gdb is a fairly standard debugger for C code
    • You make your code debuggable by adding the "-g" flag to the compiler
      • This is easy to do if you're using make
    • We'll cover simple use of gdb in class

Extreme Programming

  • Tag team programming (partner “over the shoulder”) can be very productive
    • Not in solo assignments at WSU, though
    • Tend to be >2x as productive as alone
  • Someone else is not seeing right past your bugs

When all else fails

  • Take a break, stretch, go play tennis, whatever
    • Our minds are remarkably able to work on problems subconsciously
  • Consider that it could be a bug in the compiler, OS, or a hardware problem
    • This is not often the case, but it can happen
    • Reducing it to a test case will prove or disprove this theory

Other people's bugs

  • Other people's bugs are often even harder than your own
  • If you have the source code
    • You first have to familiarize yourself with the code
    • Many of the tools and techniques mentioned here will help
  • If you don't have the source code
    • Make sure it really is a bug; try to isolate it
    • Make sure you're using the latest version of the program
      • If you aren't, the answer to your bug report is almost guaranteed to be "upgrade"
    • The better your bug report, the better the response is likely to be

Some more debugging help

  • Assert macro
  • TRACE macro (we will see soon)
  • Debug flags setup from SR Language (courtesy of Gregg Townsend; we will see soon)