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

Effective Debugging - RubyconfIndia

Effective Debugging - RubyconfIndia

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

June 22, 2013
Tweet

More Decks by Jonathan Wallace

Other Decks in Programming

Transcript

  1. Overview • Case Study • Recap and advanced commands •

    Debugging Libraries 2 Saturday, June 22, 13
  2. Case Study 3 Saturday, June 22, 13 - here’s the

    situation. - you’ve been handed an existing project by your boss..
  3. Sacculina Carcini 4 Saturday, June 22, 13 - 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
  4. 5 Saturday, June 22, 13 - this project has a

    test suite - previous developer completed feature and hands off a “green” test suite (or so he says)
  5. 10 Saturday, June 22, 13 - turnip / rspec, explain

    that steps are executed in order. - execution stops rspec expectation is not met.
  6. 11 Saturday, June 22, 13 - not enough information on

    line 12 to tell us why it failed - let’s look at the stack trace in the rspec output
  7. 12 Saturday, June 22, 13 let’s examine the step definition

    on line 32 to see if it can tell us more
  8. 13 Saturday, June 22, 13 - here we are in

    the step definition file
  9. 14 Saturday, June 22, 13 - 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..
  10. 15 Saturday, June 22, 13 - here’s the feature -

    and we know the failure is on line 12...
  11. 16 Saturday, June 22, 13 - but we don’t know

    when the crab’s payload should have its infection - it could happen on lines 3 through 11..
  12. 17 Saturday, June 22, 13 - 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’..
  13. 18 Saturday, June 22, 13 - we have to do

    two things to use the ‘debugger’ gem
  14. 19 Saturday, June 22, 13 - update our gem file

    to include a reference to the ‘debugger’ gem
  15. 20 Saturday, June 22, 13 - call the debugger method

    which pauses our application. - but where should we put it?...
  16. 21 Saturday, June 22, 13 - there’s no relationship between

    host, the crab, and parasite, the sacculina carcini
  17. 22 Saturday, June 22, 13 - instead, let’s place our

    debugger statement at the first step where the parasite and the host interact. - note that we have the ruby statement “true” after the debugger method call. - the reason for this is that execution is paused on the ruby expression immediately following the debugger method call. - let’s run the debugger
  18. 24 Saturday, June 22, 13 - let’s take a moment

    to discuss what we see in the debugger
  19. 28 Saturday, June 22, 13 - 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...
  20. 29 Saturday, June 22, 13 - 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
  21. 33 Saturday, June 22, 13 - we’ve now advanced the

    debugger session to line 11. we have yet to execute the ruby expression on line 11 (we have executed the “true” statement on line 10. - let’s “step” again and see what happens
  22. 34 Saturday, June 22, 13 - note that executing ‘true’

    did not change our displayed ruby expression
  23. 36 Saturday, June 22, 13 - first thing to note

    is that our displayed ruby expression is still nil - secondly, whoa, where are we..
  24. 37 Saturday, June 22, 13 - 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
  25. 38 Saturday, June 22, 13 - 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.
  26. 45 Saturday, June 22, 13 - 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? ...
  27. 46 Saturday, June 22, 13 - well, i can think

    of one way, we could add ‘debugger; true’ statements at lines 16, 20, 24, and 28...
  28. 47 Saturday, June 22, 13 - so instead of just

    one debugger statement, we would have five...
  29. 48 Saturday, June 22, 13 - however, there’s a better

    way. let’s make use of the capabilities provided by the debugger tool.
  30. 67 Saturday, June 22, 13 - the crab payload in

    our display list hasn’t changed from 0x007
  31. 68 Saturday, June 22, 13 - 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’...
  32. Case Study Recap • debugger • display • step •

    break • continue • next 82 Saturday, June 22, 13 - 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.
  33. Case Study Recap • debugger • disp • step •

    break • next 83 Saturday, June 22, 13 - 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.
  34. Case Study Recap • debugger • display • step •

    break • next 84 Saturday, June 22, 13 - also called watch
  35. Case Study Recap • debugger • display <ruby expression> •

    step • break • next 85 Saturday, June 22, 13
  36. Case Study Recap • debugger • disp <ruby expression> •

    step • break • next 86 Saturday, June 22, 13
  37. Case Study Recap • debugger • disp[lay] • step •

    break • next 87 Saturday, June 22, 13
  38. Case Study Recap • debugger • disp[lay] • step [n]

    • break • next 88 Saturday, June 22, 13
  39. Case Study Recap • debugger • disp[lay] • step •

    break • next 89 Saturday, June 22, 13
  40. Case Study Recap • debugger • disp[lay] • step •

    break <file name>:<line number> • next 90 Saturday, June 22, 13
  41. Case Study Recap • debugger • disp[lay] • step •

    b <file name>:<line number> • next 91 Saturday, June 22, 13
  42. Case Study Recap • debugger • disp[lay] • step •

    b Class.class_method • next 92 Saturday, June 22, 13
  43. Case Study Recap • debugger • disp[lay] • step •

    b Class#instance_method • next 93 Saturday, June 22, 13
  44. Case Study Recap • debugger • display • step •

    break • continue • next 94 Saturday, June 22, 13 - continue execution until the application completes or we hit another breakpoint
  45. Case Study Recap • debugger • disp[lay] • step •

    break • next 95 Saturday, June 22, 13
  46. Case Study Recap • debugger • disp[lay] • step •

    break • next [n] 96 Saturday, June 22, 13
  47. Case Study Recap • debugger • disp[lay] • step •

    break • n [n] 97 Saturday, June 22, 13
  48. 100 Saturday, June 22, 13 - remember in our case

    study when we were on line eleven and we “stepped” into the attach method on @sacculini_carcini?...
  49. 101 Saturday, June 22, 13 - and at that time

    we stepped 3? - what if we had a loop, or many many lines of code?...
  50. 102 Saturday, June 22, 13 - so instead of step,

    we use “finish” which execute code until the current stack has completed
  51. What did we miss? • finish • source 104 Saturday,

    June 22, 13 - source has an analog called save, but in my explorations it does not save displayed ruby expressions in debugger
  52. Debugger Versions • 1.8 -- ruby-debug • 1.9 -- debugger,

    ruby-debug19, debugger2 • 2.0 -- debugger, byebug, debugger2 108 Saturday, June 22, 13 - lag time between new version of ruby and a fully supported debugger - debugger2 / byebug - use external C APIs
  53. Why? 110 Saturday, June 22, 13 - why? coupling! -

    let’s take a look at the change log for the debugger gem...
  54. Ruby’s C API 113 Saturday, June 22, 13 - 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
  55. Debugger Versions • 1.8 -- ruby-debug • 1.9 -- debugger,

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

    115 Saturday, June 22, 13 - for ruby 1.8.7 - if you’re using debugger, byebug or debugger2, these are the defaults
  57. Debugger Versions • 1.8 -- ruby-debug • 1.9 -- debugger,

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

    debugger2, ruby-debug19 • 2.0 -- debugger, debugger2, byebug 117 Saturday, June 22, 13 - lag time between new version of ruby and a fully supported debugger - debugger2 / byebug - use external C APIs
  59. Pry • “powerful alternative to [...] IRB [...]” • syntax

    highlighting • “flexible plugin architecture” 119 Saturday, June 22, 13 - here’s the important thing, PRY is a REPL (read eval print loop) - let’s take a look; two things to do
  60. 123 Saturday, June 22, 13 - similar display, column numbers

    on the left, hash rocket indicates the current line - pretty colors
  61. 124 Saturday, June 22, 13 - binding.pry stops us before

    the binding.pry statement on line 10 so we don’t need “; true”
  62. 126 Saturday, June 22, 13 - notice we have to

    use “break”, no shortcuts - and we must use the relative path from the project directory to when specifying the file
  63. 127 Saturday, June 22, 13 - after hitting enter, we

    see info about the break point...
  64. 128 Saturday, June 22, 13 - in addition we see

    the context too for the break point.
  65. 130 Saturday, June 22, 13 - pry tells us how

    often the break point is hit - we have a few more things to note about pry...
  66. byebug 133 Saturday, June 22, 13 - mashup of debase,

    another debugger for ruby 2.0 (C ext part) and debugger (lib and test dirs) - i didn’t investigate debase much because there’s not a lot of documentation
  67. 135 Saturday, June 22, 13 - only for ruby 2.0.

    otherwise works as debugger in terms of commands, etc.
  68. 138 Saturday, June 22, 13 - for JRuby, feel free

    to use any of the Java tools for debugging
  69. Overview • Case Study • Recap and advanced commands •

    Debugging Libraries 139 Saturday, June 22, 13 - next, step, break, continue, display - finish, source - ruby-debug 1.8.7, debugger for 1.9, byebug for 2.0 - can use pry w/debugger and byebug)
  70. Slides and Code and Image • https://speakerdeck.com/jwallace/effective- debugging • https://github.com/wallace/

    sacculina_carcini.git • http://www.flickr.com/photos/ 81858878@N00/9025250716/in/photolist- eKwLAY 140 Saturday, June 22, 13
  71. Get to know me! • http://blog.jonathanrwallace.com/about • [email protected] • @jonathanwallace

    • http://www.bignerdranch.com/about_us/ nerds/jonathan_wallace 141 Saturday, June 22, 13 - thanks to Big Nerd Ranch, organizers and people who helped me with this talk