Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Friday, November 15, 13

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

NO. Friday, November 15, 13

Slide 8

Slide 8 text

READ THE ERROR MESSAGE Friday, November 15, 13

Slide 9

Slide 9 text

/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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Start at the top. Friday, November 15, 13

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

/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

Slide 14

Slide 14 text

Read the line number Friday, November 15, 13

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Unexpected Behavior Friday, November 15, 13

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

“I deduce.” Friday, November 15, 13

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

Friday, November 15, 13

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

Make the problem more concrete Friday, November 15, 13

Slide 53

Slide 53 text

Sketch things out Friday, November 15, 13

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

Rubber duck debugging Friday, November 15, 13

Slide 58

Slide 58 text

Trust no one. Friday, November 15, 13

Slide 59

Slide 59 text

Friday, November 15, 13

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

A few Git tricks Friday, November 15, 13

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

Debuggers Friday, November 15, 13

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

Friday, November 15, 13

Slide 88

Slide 88 text

WHEN THINGS GET REALLY WEIRD Friday, November 15, 13

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

Friday, November 15, 13

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

$ bundle open gem_name Friday, November 15, 13

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

Friday, November 15, 13

Slide 98

Slide 98 text

Friday, November 15, 13

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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