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

Effective Debugging - Big Nerd Ranch Tech Talk

Effective Debugging - Big Nerd Ranch Tech Talk

Debugging is an art. And to be an effective artist, an artist must be intimately familiar with their tools. In this talk, we'll start gently and finish strong to ensure that there's something for everyone. We'll cover when to use a debugger, which debugger to use, and how to use the debugger, and how to quickly configure your debugger for maximum utility. We'll touch briefly on pry and why pry is not a debugger, except when it is.

Developers are always looking for ways to boost productivity. Effective debugging allows one to more quickly discover inaccuracies between our expectations and how the software actually behaves.

Jonathan Wallace

December 06, 2013
Tweet

More Decks by Jonathan Wallace

Other Decks in Programming

Transcript

  1. Effective Debugging All the techniques and tactics described herein are

    ways to account for the limited working memory and cognitive power of humans.
  2. What is debugging? We often thinking of debugging as “squashing

    bugs” but it is actually resolving root causes of symptoms. To summarize, debugging is identifying the root cause of the actual behavior of the system when it differs from the desired behavior.
  3. What is effective debugging? Effective debugging is efficiently identifying the

    root cause of the actual behavior of the system when it differs from the desired behavior.
  4. Overview • Definitions • Have a Process • Know Your

    Tools • Available Debugging Libraries • Case Study • Recap and advanced commands • Pry
  5. Have a Process • Understand the System • Make It

    Fail • Quit Thinking and Look • Divide and Conquer • Change One Thing at a Time • Keep an Audit Trail • Check the Plug • Get a Fresh View • If You Didn't Fix It, It Ain't Fixed
  6. Understand the System Read your bootstrap documentation, application README, tests,

    and READMEs of any libraries your using. Run the tests even. If this isn’t an API and it has a client side interface, practice using it as a user. ! Once my team spent two days debugging a “memory leak” performance regression because we didn’t know there was a gem that disabled GC!
  7. Make it Fail You must be able to reproduce the

    bug. What is the minimum set of user input and data necessary to reproduce it. If you can’t reproduce it, you won’t be able to verify the root cause or causes fixed it!
  8. Quit Thinking and Look Developers well acquainted with an application

    will often make an assumption and jump to a conclusion as to “what is wrong.” Check your ego and read the error. Read the stack trace. Read the functional spec.
  9. Divide and Conquer Binary searches are much faster than a

    bubble sort. Would you sequentially search through the dictionary for the definition of a word you’re looking for? NOPE.
  10. Change One Thing at a Time Again, these points are

    all obvious. If you change more than one thing, how can you be sure what fixed?
  11. Keep an Audit Trail Terrible bugs may take a terrible

    amount of time to resolve. If you spend days on a one bug, you need to be clear about what you’ve already tried. This will come in handy in later steps too.
  12. Get a Fresh View Rubber ducking allows someone else to

    check your assumptions. They’ll double check your process in a different way. Maybe they’re an expert or have experience in a different area. Two heads are better than one.
  13. If You Didn't Fix It, It Ain't Fixed If you

    forgot or skipped the “Make It Fail” step, you’re not going to know if it was your work that fixed it. Verify that your fix really fixed it.
  14. Have a Process • Understand the System • Make It

    Fail • Quit Thinking and Look • Divide and Conquer • Change One Thing at a Time • Keep an Audit Trail • Check the Plug • Get a Fresh View • If You Didn't Fix It, It Ain't Fixed
  15. Available Debugger Libraries • 1.8 -- ruby-debug • 1.9 --

    debugger, ruby-debug19, debugger2 • 2.0 -- debugger, byebug, debugger2 There’s a lot of options for debuggers in the ruby ecosystem.
  16. Why? - why? coupling! - let’s take a look at

    the change log for the debugger gem...
  17. Ruby’s C API - in the past, most debugging tools

    are tightly coupled to the C internals. - because the debuggers were hooking into internals, every time ruby changed, you needed a new debugger
  18. Debugger Versions • 1.8 -- ruby-debug • 1.9 -- debugger,

    debugger2, ruby-debug19 • 2.0 -- debugger, debugger2, byebug - lag time between new version of ruby and a fully supported debugger - debugger2 / byebug - use external C APIs
  19. ~/.rdebugrc • set autoreload • set autoeval • set autolist


    - for ruby 1.8.7 - if you’re using debugger, byebug or debugger2, these are the defaults
  20. Debugger Versions • 1.8 -- ruby-debug • 1.9 -- debugger,

    debugger2, ruby-debug19 • 2.0 -- debugger, debugger2, byebug - lag time between new version of ruby and a fully supported debugger - debugger2 / byebug - use external C APIs
  21. Debugger Versions • 1.8 -- ruby-debug • 1.9 -- debugger,

    debugger2, ruby-debug19 • 2.0 -- debugger, debugger2, byebug - lag time between new version of ruby and a fully supported debugger - debugger2 / byebug - use external C APIs
  22. Case Study - use byebug - here’s the situation. -

    you’ve been handed an existing project by your boss..
  23. Have a Process • Understand the System • Make It

    Fail • Quit Thinking and Look • Divide and Conquer • Change One Thing at a Time • Keep an Audit Trail • Check the Plug • Get a Fresh View • If You Didn't Fix It, It Ain't Fixed
  24. Sacculina Carcini - parasitic barnacle - takes over the host;

    host no longer molts; male crabs act like female crabs - http://www.flickr.com/photos/81858878@N00/9025250716/in/photolist-eKwLAY
  25. - this project has a test suite - previous developer

    completed feature and hands off a “green” test suite (or so he says)
  26. - turnip / rspec, explain that steps are executed in

    order. - execution stops rspec expectation is not met.
  27. - not enough information on line 12 to tell us

    why it failed - let’s look at the stack trace in the rspec output
  28. - the internal state of the crab should have a

    key that points to the parasite - let’s take a step back and review the feature again..
  29. - but we don’t know when the crab’s payload should

    have its infection - it could happen on lines 3 through 11..
  30. - at this point, it may be tempting to investigate

    the internal details of the crab class and its payload and how that works but that would be premature at this point. instead of anticipating where the problems lies, we’re going to allow our tool, the debugger, to direct our investigations. we’re not making assumptions as to the root cause of the error. let’s stay “assumption free.” - so, let’s use the ruby gem ‘debugger’..
  31. - instead, let’s place our debugger statement at the first

    step where the parasite and the host interact. - note that execution is paused on the ruby expression immediately following the debugger method call. - let’s run the debugger
  32. - and that is indicated by the presence of the

    hash rocket. - great. now we know where we are in the debugger session, let’s examine the code in this step...
  33. - we have two lines. - ah, line 12 looks

    interesting. do you remember what the original failure? it was related to the crab’s payload. - the crab’s payload was nil when the test expected there to be a value - let’s add the crab’s payload as a display (or watched) variable
  34. - first thing to note is that our displayed ruby

    expression is still nil - secondly, whoa, where are we..
  35. - we’re actually in a new file. we’re inside the

    attach method of the parasite. - the debugger command “step” goes into a method definition. we “step” into
  36. - a little different than last time. we provide a

    number after step. this indicates how many times to run the step command. this is useful when you want to issue the same command multiple times. this will run “step” 3 times for us.
  37. - we’re interested in what happens at the turnip step

    levels of lines 8, 9, 10 and 11. - how can we quickly stop execution at those lines? ...
  38. - well, i can think of one way, we could

    add ‘debugger’ statements at lines 16, 20, 24, and 28...
  39. - however, there’s a better way. let’s make use of

    the capabilities provided by the debugger tool.
  40. - the last time we stepped into a method, we

    took a detour that wasn’t necessary or informative. - let’s explore another debugger command, ‘next’...
  41. Recap and Advanced Commands - here’s the situation. - you’ve

    been handed an existing project by your boss..
  42. Case Study Recap • debugger • display • step •

    break • continue • next - debugger is a method that you may place in your application that will pause its execution allowing you to examine state, modify state, set further break points.
  43. Case Study Recap • debugger • disp • step •

    break • next - debugger is a method that you may place in your application that will pause its execution allowing you to examine state, modify state, set further break points.
  44. Case Study Recap • debugger • display • step •

    break • next - also called watch
  45. Case Study Recap • debugger • disp[lay] • step •

    break <file name>:<line number> • next
  46. Case Study Recap • debugger • disp[lay] • step •

    b <file name>:<line number> • next
  47. Case Study Recap • debugger • display • step •

    break • continue • next - continue execution until the application completes or we hit another breakpoint
  48. - remember in our case study when we were on

    line eleven and we “stepped” into the attach method on @sacculini_carcini?...
  49. - and at that time we stepped 3? - what

    if we had a loop, or many many lines of code?...
  50. - so instead of step, we use “finish” which execute

    code until the current stack has completed
  51. - automatically evaluate ruby expressions - show full file paths

    or just the filename - - display context - auto start irb when prompt is shown
  52. Pry • “powerful alternative to [...] IRB [...]” • syntax

    highlighting • “flexible plugin architecture” - here’s the important thing, PRY is a REPL (read eval print loop) - let’s take a look; two things to do
  53. - similar display, column numbers on the left, hash rocket

    indicates the current line - pretty colors
  54. - notice we have to use “break”, no shortcuts -

    and we must use the relative path from the project directory to when specifying the file
  55. - pry tells us how often the break point is

    hit - we have a few more things to note about pry...
  56. - for JRuby, feel free to use any of the

    Java tools for debugging
  57. Other tools? • #source_location • puts '*'*80 • pp •

    gem which • ap - awesome_print • editor plugins (ctags in vim, cucumber step definitions)
  58. Slides and Code and Image • https://speakerdeck.com/jwallace/effective- debugging-bnr-tech-talk • https://github.com/wallace/

    sacculina_carcini.git • http://www.flickr.com/photos/ 81858878@N00/9025250716/in/photolist- eKwLAY
  59. Credits and References and Further Reading • http://blog.regehr.org/archives/199 • http://blog.regehr.org/archives/849

    • http://www.amazon.com/Debugging-David-J-Agans-ebook/ dp/B002H5GSZ2/ref=sr_1_1? s=books&ie=UTF8&qid=1386325548&sr=1-1&keywords=d ebugging%3A+the+9+indispensable+rules+for+finding+even +the+most+elusive+software+and+hardware+problems • http://blog.bignerdranch.com/4390-slide-design-developers/ • https://kuler.adobe.com/vintage-card-color-theme-3165833/
  60. Get to know me! KNOW ME http://blog.jonathanrwallace.com/about FOLLOW ME @jonathanwallace

    WORK WITH ME http://www.bignerdranch.com CODE WITH ME github/wallace - thanks to Big Nerd Ranch, organizers and people who helped me with this talk