Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

A toolbelt of seasoned bug hunter - Damir Zekic

80 views

Published on

Video: https://youtu.be/So9ft63WVLY

Ruby Meditation #19
November 25, 2017
Kyiv

Published in: Technology
  • Be the first to comment

  • Be the first to like this

A toolbelt of seasoned bug hunter - Damir Zekic

  1. 1. A Toolbelt of a Seasoned Bug Hunter Damir Zekić
  2. 2. (["foo")
  3. 3. Baaaad bugs Not so bad bugs
  4. 4. Silent bugs Loud bugs
  5. 5. 2016: a debugging odyssey
  6. 6. Step 1: Reproduce
  7. 7. Step 1: Reproduce SUCCESS
  8. 8. Step 2: What introduced it?
  9. 9. git bisect
  10. 10. 13 37 c0 ff ee c0 de a0
  11. 11. 13 37 c0 ff ee c0 de a0 bug is present here "bad"
  12. 12. 13 37 c0 ff ee c0 de a0 bug is present here "bad" no bug 7 commits ago "good"
  13. 13. 13 37 c0 ff ee c0 de a0 bug is present here "bad" no bug 7 commits ago "good"
  14. 14. 13 37 c0 ff ee c0 de a0 bug is present here "bad" no bug 7 commits ago "good"
  15. 15. 13 37 c0 ff ee c0 de a0 bug is present here "bad" no bug 7 commits ago "good"
  16. 16. 13 37 c0 ff ee c0 de a0 bug is present here "bad" no bug 7 commits ago "good"
  17. 17. 13 37 c0 ff ee c0 de a0 bug is present here "bad" no bug 7 commits ago "good"
  18. 18. 13 37 c0 ff ee c0 de a0 bug is present here "bad" no bug 7 commits ago "good"
  19. 19. 13 37 c0 ff ee c0 de a0 bug is present here "bad" no bug 7 commits ago "good"
  20. 20. 13 37 c0 ff ee c0 de a0 cli-ff-hanger
  21. 21. Every commit must be stable
  22. 22. But, which commit was "good"?!
  23. 23. 13 37 c0 ff ee c0 de a0 no bug 7 commits ago "good"
  24. 24. $ ./find_slow.rb
  25. 25. Step 2: What introduced it? UNSURE
  26. 26. Brainstorming: Is it a memory leak?
  27. 27. A Problem: Ruby doesn't release memory back to OS
  28. 28. Brainstorming: Is it a memory leak?UNSURE
  29. 29. Assume it is and check heap dumps
  30. 30. require 'objspace' ObjectSpace.trace_object_allocations_start class Foo def bar puts "Hello, world!" end end
 foo = Foo.new foo.bar file = File.open("/tmp/heap.dump", 'w') ObjectSpace.dump_all(output: file) file.close
  31. 31. $ wc -l /tmp/heap.dump 33297 /tmp/heap.dump
  32. 32. {"address":"0x7f9fa7076ea0", "type":"STRING", "class":"0x7f9fa70cfe10", "embedded":true, "bytesize":13, "value":"Hello, world!", "encoding":"UTF-8", "file":"(irb)", "line":5, "method":"bar", "generation":13, "memsize":40, "flags": {"wb_protected":true}} {"address":"0x7f9fa7076ec8", "type":"IMEMO", "class":"0x7f9fa70dc2f0", "memsize":40, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}} {"address":"0x7f9fa7076ef0", "type":"IMEMO", "references":["0x7f9fa70dd4e8"], "memsize":40, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}} {"address":"0x7f9fa7076f18", "type":"STRING", "class":"0x7f9fa70cfe10", "frozen":true, "embedded":true, "fstring":true, "bytesize":5, "value":"abort", "encoding":"US-ASCII", "memsize":40, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}} {"address":"0x7f9fa7076f40", "type":"STRING", "class":"0x7f9fa70cfe10", "frozen":true, "bytesize":59, "capacity":127, "value":"/Users/damir/.rbenv/versions/2.4.1/lib/ruby/x86_64-darwin16", "memsize":168, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}} {"address":"0x7f9fa7076f68", "type":"IMEMO", "class":"0x7f9fa70dc2f0", "memsize":40, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}} {"address":"0x7f9fa7076f90", "type":"IMEMO", "references":["0x7f9fa70dd4e8"], "memsize":40, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}} {"address":"0x7f9fa7076fb8", "type":"IMEMO", "class":"0x7f9fa70dc2f0", "memsize":40, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}} {"address":"0x7f9fa7076fe0", "type":"IMEMO", "references":["0x7f9fa70dd4e8"], "memsize":40, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}} {"address":"0x7f9fa7077008", "type":"IMEMO", "class":"0x7f9fa70dc2f0", "memsize":40, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}} {"address":"0x7f9fa7077030", "type":"IMEMO", "references":["0x7f9fa70dd4e8"], "memsize":40, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}} {"address":"0x7f9fa7077058", "type":"STRING", "class":"0x7f9fa70cfe10", "frozen":true, "embedded":true, "fstring":true, "bytesize":5, "value":"spawn", "encoding":"US-ASCII", "memsize":40, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}}
  33. 33. {"address":"0x7f9fa7076ea0", "type":"STRING", "class":"0x7f9fa70cfe10", "embedded":true, "bytesize":13, "value":"Hello, world!", "encoding":"UTF-8", "file":"(irb)", "line":5, "method":"bar", "generation":13, "memsize":40, "flags":{"wb_protected":true}}
  34. 34. $ gem install heapy
  35. 35. $ ./analyze_heapy_diffs.rb
  36. 36. Class DSL objects survive longest
  37. 37. !
  38. 38. Brainstorming: Let's trace a call stack
  39. 39. Flamegraphs
  40. 40. Brainstorming: Let's trace a call stackSUCCESS
  41. 41. Internal framework creates controllers Classes created by routing don't get destroyed Router removes methods from all controllers
  42. 42. Now let's fix it!

×