Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Debugging: The Science of Deduction

Debugging: The Science of Deduction

Tips for debugging code in Ruby.

Danielle Sucher

November 14, 2013
Tweet

More Decks by Danielle Sucher

Other Decks in Programming

Transcript

  1. THE SCIENCE OF DEDUCTION
    [email protected] • @DanielleSucher
    DEBUGGING
    Friday, November 15, 13

    View Slide

  2. "People write programs without
    any expectation that they will be
    right the first time."
    - David Lorge Parnas
    Friday, November 15, 13

    View Slide

  3. Friday, November 15, 13

    View Slide

  4. Let’s start simple.
    Friday, November 15, 13

    View Slide

  5. When you
    get an error
    message
    Friday, November 15, 13

    View Slide

  6. “Oh, I think I know what
    went wrong..!”
    Friday, November 15, 13

    View Slide

  7. NO.
    Friday, November 15, 13

    View Slide

  8. READ THE ERROR
    MESSAGE
    Friday, November 15, 13

    View Slide

  9. /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/attribute_assigner.rb:14:in `tap'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/attribute_assigner.rb:14:in `object'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/evaluation.rb:12:in `object'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/strategy/build.rb:9:in `result'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/factory.rb:42:in `run'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/factory_runner.rb:23:in `block in run'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/activesupport-4.0.1/
    lib/active_support/notifications.rb:161:in `instrument'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/factory_runner.rb:22:in `run'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/strategy_syntax_method_registrar.rb:19:in `block in
    define_singular_strategy_method'
    /Users/stan/projects/rails4/spec/models/project_spec.rb:21:in `block
    (4 levels) in '
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/rspec-core-2.14.5/
    lib/rspec/core/memoized_helpers.rb:199:in `block (2 levels) in let'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/rspec-core-2.14.5/
    lib/rspec/core/memoized_helpers.rb:199:in `fetch'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/rspec-core-2.14.5/
    lib/rspec/core/memoized_helpers.rb:199:in `block in let'
    Friday, November 15, 13

    View Slide

  10. How do you find
    the important stuff?
    Friday, November 15, 13

    View Slide

  11. Start at the top.
    Friday, November 15, 13

    View Slide

  12. Skim for lines that refer to
    your project’s codebase
    Friday, November 15, 13

    View Slide

  13. /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/attribute_assigner.rb:14:in `tap'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/attribute_assigner.rb:14:in `object'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/evaluation.rb:12:in `object'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/strategy/build.rb:9:in `result'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/factory.rb:42:in `run'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/factory_runner.rb:23:in `block in run'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/activesupport-4.0.1/
    lib/active_support/notifications.rb:161:in `instrument'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/factory_runner.rb:22:in `run'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/factory_girl-4.2.0/
    lib/factory_girl/strategy_syntax_method_registrar.rb:19:in `block in
    define_singular_strategy_method'
    /Users/stan/projects/rails4/spec/models/project_spec.rb:21:in `block
    (4 levels) in '
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/rspec-core-2.14.5/
    lib/rspec/core/memoized_helpers.rb:199:in `block (2 levels) in let'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/rspec-core-2.14.5/
    lib/rspec/core/memoized_helpers.rb:199:in `fetch'
    /Users/stan/.rvm/gems/ruby-1.9.3-p448@rails4/gems/rspec-core-2.14.5/
    lib/rspec/core/memoized_helpers.rb:199:in `block in let'
    /Users/stan/projects/rails4/spec/models/project_spec.rb:24:in `block
    Friday, November 15, 13

    View Slide

  14. Read the line
    number
    Friday, November 15, 13

    View Slide

  15. google the error
    (no, really, you’re not smarter
    than google)
    Friday, November 15, 13

    View Slide

  16. Unexpected Behavior
    Friday, November 15, 13

    View Slide

  17. “I don’t guess.
    I observe.”
    Friday, November 15, 13

    View Slide

  18. “And once I’ve
    observed...”
    Friday, November 15, 13

    View Slide

  19. “I deduce.”
    Friday, November 15, 13

    View Slide

  20. Formulate a hypothesis.
    Try to disprove it.
    Repeat as needed.
    Friday, November 15, 13

    View Slide

  21. Where do you start looking?
    Friday, November 15, 13

    View Slide

  22. The Streetlight Effect
    searching where the keys fell
    vs
    searching where the light is
    Friday, November 15, 13

    View Slide

  23. Start
    looking
    where
    the
    light
    is
    Friday, November 15, 13

    View Slide

  24. First test the theories
    you can disprove the fastest
    Friday, November 15, 13

    View Slide

  25. To test your hypotheses,
    you need to
    reproduce the bug
    Friday, November 15, 13

    View Slide

  26. If you can’t reproduce the bug,
    what’s different
    about your environment?
    Friday, November 15, 13

    View Slide

  27. Watch somebody else
    reproduce the problem.
    Friday, November 15, 13

    View Slide

  28. Sometimes it’s all in the timing
    Friday, November 15, 13

    View Slide

  29. Even partial patterns
    can give you useful data
    Friday, November 15, 13

    View Slide

  30. the 500 mile bug
    http://www.ibiblio.org/harris/
    500milemail.html
    Friday, November 15, 13

    View Slide

  31. Try to break things down into
    smaller, self-contained, pieces.
    Friday, November 15, 13

    View Slide

  32. Don’t even try
    to understand everything
    Friday, November 15, 13

    View Slide

  33. Friday, November 15, 13

    View Slide

  34. Miller’s Law
    The average person can only hold
    7 ± 2
    items in working memory
    Friday, November 15, 13

    View Slide

  35. It’s okay to think of
    the rest of the system
    as a black box
    Friday, November 15, 13

    View Slide

  36. Break apart methods so you can
    test smaller chunks of logic
    separately
    Friday, November 15, 13

    View Slide

  37. Comment out parts of your code
    so you can focus on one
    piece at a time
    Friday, November 15, 13

    View Slide

  38. Refactoring and adding tests
    (or even just fixing typos)
    keeps you focused
    and improves
    your understanding
    Friday, November 15, 13

    View Slide

  39. With really gnarly code
    write tests to
    document existing behavior
    Friday, November 15, 13

    View Slide

  40. "...what are the facts, and what is
    the truth that the facts bear out?"
    - Bertrand Russell
    Friday, November 15, 13

    View Slide

  41. Is the method you’re looking at
    even being called at all?
    Friday, November 15, 13

    View Slide

  42. def might_be_called
    puts “IN MIGHT_BE_CALLED”
    puts caller
    # ...
    end
    Friday, November 15, 13

    View Slide

  43. “What they
    don’t
    confess
    to is
    almost
    always
    more
    interesting.”
    Friday, November 15, 13

    View Slide

  44. What are the actual inputs
    your method is receiving?
    Friday, November 15, 13

    View Slide

  45. Maybe you think you’re
    getting nil, but
    you’re getting ‘’ or [‘’]
    instead
    Friday, November 15, 13

    View Slide

  46. Is there a rescue in the way,
    swallowing useful errors?
    Friday, November 15, 13

    View Slide

  47. What is the state of the universe?
    Friday, November 15, 13

    View Slide

  48. Follow the money logs
    $ tail -f log/whatevs.log
    Friday, November 15, 13

    View Slide

  49. Does doing things in a
    different order
    lead to different results?
    Friday, November 15, 13

    View Slide

  50. Possible Ordering Problems
    Methods with side effects
    Rails autoload order
    Database left in a dirty state
    Friday, November 15, 13

    View Slide

  51. Clean out your environment
    (if at all possible)
    Friday, November 15, 13

    View Slide

  52. Make the
    problem
    more concrete
    Friday, November 15, 13

    View Slide

  53. Sketch things out
    Friday, November 15, 13

    View Slide

  54. Wave your hands around
    in the air
    placing pieces of your system
    in imaginary 3d space
    Friday, November 15, 13

    View Slide

  55. “I need to go
    to my mind
    palace.”
    Friday, November 15, 13

    View Slide

  56. Question your assumptions.
    (Write a list or even an informal
    proof, if necessary.)
    Friday, November 15, 13

    View Slide

  57. Rubber duck
    debugging
    Friday, November 15, 13

    View Slide

  58. Trust no one.
    Friday, November 15, 13

    View Slide

  59. Friday, November 15, 13

    View Slide

  60. “The only truly accurate
    comment I've seen was just
    cursing, in Swedish.”
    - Scott Vokes (@silentbicycle)
    Friday, November 15, 13

    View Slide

  61. “Without a debugger, you
    basically have to go to the next
    step; understand what the
    program does.”
    - Linus Torvalds
    Friday, November 15, 13

    View Slide

  62. print statement debugging
    puts “*” * 20
    puts “foo: #{foo.inspect}”
    puts “*” * 20
    Friday, November 15, 13

    View Slide

  63. Where is this method defined?
    m = Foo.new.method(:do_stuff)
    m.source_location
    => [filename, line_number]
    Friday, November 15, 13

    View Slide

  64. “Ideas are tested by experiment.
    That is the core of science.”
    - Zombie Richard Feynman
    (via xkcd)
    Friday, November 15, 13

    View Slide

  65. Experiment with
    small pieces of the code
    in IRB or Pry
    Friday, November 15, 13

    View Slide

  66. Focus on what’s
    changed
    since the problem started
    Friday, November 15, 13

    View Slide

  67. A few Git tricks
    Friday, November 15, 13

    View Slide

  68. test on a different branch
    or a different commit
    Friday, November 15, 13

    View Slide

  69. git bisect
    binary search through your
    commits to figure out when the
    problem started!
    Friday, November 15, 13

    View Slide

  70. Running git bisect manually
    $ git bisect start
    $ git bisect good SHA
    $ git bisect bad HEAD
    Friday, November 15, 13

    View Slide

  71. Running git bisect
    automatically
    $ git bisect start HEAD HEAD~10
    $ git bisect run rspec spec/
    Friday, November 15, 13

    View Slide

  72. git blame
    (not actually
    for blaming
    people!)
    Friday, November 15, 13

    View Slide

  73. The person who wrote this code
    may have been an idiot.
    Or they may have been
    a mad genius.
    Friday, November 15, 13

    View Slide

  74. Look at the original context
    $ git blame -L(range) filename
    $ git show SHA
    Friday, November 15, 13

    View Slide

  75. But what about whitespace
    changes?
    $ git blame -w filename
    (ignores whitespace)
    Friday, November 15, 13

    View Slide

  76. But what about lines that were
    just copied or moved?
    $ git blame -wCCC filename
    -w ignores whitespace
    -C detects moved/copied lines
    -CCC is like -C, but tries harder
    Friday, November 15, 13

    View Slide

  77. $ git log -p
    Includes patches, not just
    commit messages.
    You can search with /
    search_string
    Friday, November 15, 13

    View Slide

  78. $ git log -p -S “test string”
    Lists only commits where that
    string was added or deleted
    (with patches).
    Friday, November 15, 13

    View Slide

  79. Debuggers
    Friday, November 15, 13

    View Slide

  80. byebug (Ruby 2.0.x)
    debugger (Ruby 1.9.x)
    ruby-debug (Ruby 1.8.x)
    Friday, November 15, 13

    View Slide

  81. Pry
    https://github.com/pry/pry
    https://github.com/pry/pry/
    wiki/Available-plugins
    Friday, November 15, 13

    View Slide

  82. ls - list methods on an object
    cd - into objects
    wtf? - backtrace
    show-doc - prints docs
    show-method - prints source
    whereami - no really
    Pry
    Friday, November 15, 13

    View Slide

  83. binding.pry if @whatevs
    Friday, November 15, 13

    View Slide

  84. Pry-remote
    https://github.com/mon-ouie/
    pry-remote
    Friday, November 15, 13

    View Slide

  85. binding.pry_remote
    $ pry-remote
    Friday, November 15, 13

    View Slide

  86. Better Errors
    https://github.com/charliesome/
    better_errors
    Friday, November 15, 13

    View Slide

  87. Friday, November 15, 13

    View Slide

  88. WHEN THINGS GET REALLY
    WEIRD
    Friday, November 15, 13

    View Slide

  89. This shouldn’t make a difference,
    but let’s try it just in case...
    Friday, November 15, 13

    View Slide

  90. Friday, November 15, 13

    View Slide

  91. It doesn’t count if
    you’re right by accident
    Friday, November 15, 13

    View Slide

  92. “That’s clever. Is it clever?”
    “...why is it clever?”
    Friday, November 15, 13

    View Slide

  93. If you don’t understand the cause
    of the problem, it’s not fixed,
    because you can’t predict when it
    might come up again.
    Friday, November 15, 13

    View Slide

  94. Don’t be afraid to read the source
    Friday, November 15, 13

    View Slide

  95. $ bundle open gem_name
    Friday, November 15, 13

    View Slide

  96. occasionally
    the compiler
    (Rarely! But it happens.)
    Friday, November 15, 13

    View Slide

  97. Friday, November 15, 13

    View Slide

  98. Friday, November 15, 13

    View Slide

  99. “You know my methods, Watson.”
    Friday, November 15, 13

    View Slide

  100. THE SCIENCE OF DEDUCTION
    [email protected] • @DanielleSucher
    DEBUGGING
    thank you!
    Friday, November 15, 13

    View Slide