
Debugging -- Tools and Techniques
        Bugs
        Good
Clues, Easy Bugs
        No
Clues, Hard Bugs
        Debuggers
        When
all else fails
        Other
people's bugs
Reading: Programming Pearls, 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.
 - Debugging is hard 
 
 - Good coding can reduce bugs 
 
 - No one has yet figured out
     how to prevent 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
 
  
 
 
  - 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
 
  
 
 
  - If you find a bug, fix
      it
 
 
 
  
   - Human nature is not to "get back to it"
 
  
 
 
  
   - 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
 
   
  
 
 
  
   - Jupiter Cassini-Huygens
       space probe: 
 
  
 
 
  - 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
 
 
 
  - 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
 
 
 
 - 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
 
 
 
  - Sometimes a histogram
      or other chart of your data may point out flaws that are otherwise
      non-obvious
 
 
 
  - 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
 
 
 
  - 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.
 
 
 - 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!"
 
 
 - 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
 
 
 
 - 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 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 (already seen)
 
 - TRACE macro (we will see
     soon)
 
 - Debug flags setup from SR Language (courtesy of Gregg Townsend; we will see
     soon)