Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Debugging: The Science of Deduction
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Danielle Sucher
November 14, 2013
Programming
1.3k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Debugging: The Science of Deduction
Tips for debugging code in Ruby.
Danielle Sucher
November 14, 2013
More Decks by Danielle Sucher
See All by Danielle Sucher
Debugging: The Science of Deduction (2014)
daniellesucher
1
340
Negotiation for Hackers
daniellesucher
5
800
Other Decks in Programming
See All in Programming
ランチタイムLT会3周年!ランチタイムLT会を3年間続けられたお話
y0hgi
1
140
Performance Engineering for Everyone
elenatanasoiu
0
270
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
1
190
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
110
えっ!!コードを読まずに開発を!?
hananouchi
0
220
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
390
どこまでゆるくて許されるのか
tk3fftk
0
500
Claude Team Plan導入・ガイド
tk3fftk
0
210
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
510
SREの積み重ねがAI駆動開発のガードレールになった ― 7つの実践/SRE Guardrails The 7
tomoyakitaura
8
4.4k
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
790
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
320
Featured
See All Featured
Code Review Best Practice
trishagee
74
20k
Site-Speed That Sticks
csswizardry
13
1.3k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
420
Become a Pro
speakerdeck
PRO
31
6k
Building Applications with DynamoDB
mza
96
7.1k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
260
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
180
How to Ace a Technical Interview
jacobian
281
24k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
The Invisible Side of Design
smashingmag
301
52k
First, design no harm
axbom
PRO
2
1.2k
Transcript
THE SCIENCE OF DEDUCTION
[email protected]
• @DanielleSucher DEBUGGING Friday, November
15, 13
"People write programs without any expectation that they will be
right the first time." - David Lorge Parnas Friday, November 15, 13
Friday, November 15, 13
Let’s start simple. Friday, November 15, 13
When you get an error message Friday, November 15, 13
“Oh, I think I know what went wrong..!” Friday, November
15, 13
NO. Friday, November 15, 13
READ THE ERROR MESSAGE Friday, November 15, 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 <top (required)>' /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
How do you find the important stuff? Friday, November 15,
13
Start at the top. Friday, November 15, 13
Skim for lines that refer to your project’s codebase Friday,
November 15, 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 <top (required)>' /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
Read the line number Friday, November 15, 13
google the error (no, really, you’re not smarter than google)
Friday, November 15, 13
Unexpected Behavior Friday, November 15, 13
“I don’t guess. I observe.” Friday, November 15, 13
“And once I’ve observed...” Friday, November 15, 13
“I deduce.” Friday, November 15, 13
Formulate a hypothesis. Try to disprove it. Repeat as needed.
Friday, November 15, 13
Where do you start looking? Friday, November 15, 13
The Streetlight Effect searching where the keys fell vs searching
where the light is Friday, November 15, 13
Start looking where the light is Friday, November 15, 13
First test the theories you can disprove the fastest Friday,
November 15, 13
To test your hypotheses, you need to reproduce the bug
Friday, November 15, 13
If you can’t reproduce the bug, what’s different about your
environment? Friday, November 15, 13
Watch somebody else reproduce the problem. Friday, November 15, 13
Sometimes it’s all in the timing Friday, November 15, 13
Even partial patterns can give you useful data Friday, November
15, 13
the 500 mile bug http://www.ibiblio.org/harris/ 500milemail.html Friday, November 15, 13
Try to break things down into smaller, self-contained, pieces. Friday,
November 15, 13
Don’t even try to understand everything Friday, November 15, 13
Friday, November 15, 13
Miller’s Law The average person can only hold 7 ±
2 items in working memory Friday, November 15, 13
It’s okay to think of the rest of the system
as a black box Friday, November 15, 13
Break apart methods so you can test smaller chunks of
logic separately Friday, November 15, 13
Comment out parts of your code so you can focus
on one piece at a time Friday, November 15, 13
Refactoring and adding tests (or even just fixing typos) keeps
you focused and improves your understanding Friday, November 15, 13
With really gnarly code write tests to document existing behavior
Friday, November 15, 13
"...what are the facts, and what is the truth that
the facts bear out?" - Bertrand Russell Friday, November 15, 13
Is the method you’re looking at even being called at
all? Friday, November 15, 13
def might_be_called puts “IN MIGHT_BE_CALLED” puts caller # ... end
Friday, November 15, 13
“What they don’t confess to is almost always more interesting.”
Friday, November 15, 13
What are the actual inputs your method is receiving? Friday,
November 15, 13
Maybe you think you’re getting nil, but you’re getting ‘’
or [‘’] instead Friday, November 15, 13
Is there a rescue in the way, swallowing useful errors?
Friday, November 15, 13
What is the state of the universe? Friday, November 15,
13
Follow the money logs $ tail -f log/whatevs.log Friday, November
15, 13
Does doing things in a different order lead to different
results? Friday, November 15, 13
Possible Ordering Problems Methods with side effects Rails autoload order
Database left in a dirty state Friday, November 15, 13
Clean out your environment (if at all possible) Friday, November
15, 13
Make the problem more concrete Friday, November 15, 13
Sketch things out Friday, November 15, 13
Wave your hands around in the air placing pieces of
your system in imaginary 3d space Friday, November 15, 13
“I need to go to my mind palace.” Friday, November
15, 13
Question your assumptions. (Write a list or even an informal
proof, if necessary.) Friday, November 15, 13
Rubber duck debugging Friday, November 15, 13
Trust no one. Friday, November 15, 13
Friday, November 15, 13
“The only truly accurate comment I've seen was just cursing,
in Swedish.” - Scott Vokes (@silentbicycle) Friday, November 15, 13
“Without a debugger, you basically have to go to the
next step; understand what the program does.” - Linus Torvalds Friday, November 15, 13
print statement debugging puts “*” * 20 puts “foo: #{foo.inspect}”
puts “*” * 20 Friday, November 15, 13
Where is this method defined? m = Foo.new.method(:do_stuff) m.source_location =>
[filename, line_number] Friday, November 15, 13
“Ideas are tested by experiment. That is the core of
science.” - Zombie Richard Feynman (via xkcd) Friday, November 15, 13
Experiment with small pieces of the code in IRB or
Pry Friday, November 15, 13
Focus on what’s changed since the problem started Friday, November
15, 13
A few Git tricks Friday, November 15, 13
test on a different branch or a different commit Friday,
November 15, 13
git bisect binary search through your commits to figure out
when the problem started! Friday, November 15, 13
Running git bisect manually $ git bisect start $ git
bisect good SHA $ git bisect bad HEAD Friday, November 15, 13
Running git bisect automatically $ git bisect start HEAD HEAD~10
$ git bisect run rspec spec/ Friday, November 15, 13
git blame (not actually for blaming people!) Friday, November 15,
13
The person who wrote this code may have been an
idiot. Or they may have been a mad genius. Friday, November 15, 13
Look at the original context $ git blame -L(range) filename
$ git show SHA Friday, November 15, 13
But what about whitespace changes? $ git blame -w filename
(ignores whitespace) Friday, November 15, 13
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
$ git log -p Includes patches, not just commit messages.
You can search with / search_string Friday, November 15, 13
$ git log -p -S “test string” Lists only commits
where that string was added or deleted (with patches). Friday, November 15, 13
Debuggers Friday, November 15, 13
byebug (Ruby 2.0.x) debugger (Ruby 1.9.x) ruby-debug (Ruby 1.8.x) Friday,
November 15, 13
Pry https://github.com/pry/pry https://github.com/pry/pry/ wiki/Available-plugins Friday, November 15, 13
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
binding.pry if @whatevs Friday, November 15, 13
Pry-remote https://github.com/mon-ouie/ pry-remote Friday, November 15, 13
binding.pry_remote $ pry-remote Friday, November 15, 13
Better Errors https://github.com/charliesome/ better_errors Friday, November 15, 13
Friday, November 15, 13
WHEN THINGS GET REALLY WEIRD Friday, November 15, 13
This shouldn’t make a difference, but let’s try it just
in case... Friday, November 15, 13
Friday, November 15, 13
It doesn’t count if you’re right by accident Friday, November
15, 13
“That’s clever. Is it clever?” “...why is it clever?” Friday,
November 15, 13
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
Don’t be afraid to read the source Friday, November 15,
13
$ bundle open gem_name Friday, November 15, 13
occasionally the compiler (Rarely! But it happens.) Friday, November 15,
13
Friday, November 15, 13
Friday, November 15, 13
“You know my methods, Watson.” Friday, November 15, 13
THE SCIENCE OF DEDUCTION
[email protected]
• @DanielleSucher DEBUGGING thank you!
Friday, November 15, 13