SlideShare a Scribd company logo
There and Back Again
                      – or –
How I Set out to Benchmark an Algorithm and Ended
                  Up Fixing Ruby
About Me




 Name: Joshua Ballanco
About Me




Location: Ankara, Turkey
About Me




Employer:
About Me




Employer: Burnside Digital
WARNING
This is an ADVANCED presentation. While you do
not need to be an expert on the inner workings of
C Ruby, this talk does presume you are familiar
with concepts such as pointers, memory
allocation, and pages (no, not book pages,
memory pages).
If you are prone to motion sickness or become
nauseous at the sight of hexadecimal memory
addresses, this talk may not be for you.
Prelude: How can I
contribute to Ruby?
Prelude: How can I
contribute to Ruby?


     Use It!
4 Rs of Bug Reporting
• Reproduce
• Report
• Reduce
• Regress
Reproduce It!
• Can you make the bug occur every time?
  most of the time? some of the time?
• .irbrc, .gemrc, Other rc files
• Environment and Environment Variables
• rvm/rbenv
• Ask a friend
Report It!

• Ruby Bug Tracker: http://bugs.ruby-lang.org/
• All steps to reproduce, bonus points for
  attachments
• Ruby Version
• Crash log (hint: look in Console.app)
Reduce It!

• Eliminate libraries
• Simple scripts are best
• Shrink code (5 or fewer lines is ideal)
Regress It!

• Try different Ruby versions
• Better: try different Ruby releases
• Best: git bisect!
• Bonus: try different build settings
5 Rs of Bug Reporting

• Reproduce
• Report
• Reduce
• Regress
• Repair!
A long time ago in a
   faraway land...
A long time ago in a
   faraway land...
A long time ago in a
   faraway land...
A long time ago in a
   faraway land...
A long time ago in a
   faraway land...
A long time ago in a
          faraway land...




for full backstory, see: http://blogs.burnsidedigital.com/
Disaster Strikes!
> ruby delegation_bench.rb

Call one method
                      user     system      total           real
Pre-delegate      4.940000   0.020000   4.960000   (   4.954945)
Post-delegate     0.060000   0.000000   0.060000   (   0.060528)
On Demand         0.010000   0.000000   0.010000   (   0.010604)
Reversible        0.110000   0.000000   0.110000   (   0.101494)

Call one method 100 times

...

Call three methods 100 times
                     user      system      total           real
Pre-delegate     5.640000    0.000000   5.640000   (   5.640255)
Post-delegate    0.980000    0.000000   0.980000   (   0.975919)
On Demand        1.210000    0.000000   1.210000   (   1.205214)
Reversible       1.020000    0.000000   1.020000   (   1.027759)

Call three methods 10,000 times
                     user     system      total        real
Pre-delegate   ruby(5919,0x7fff732a5180) malloc: *** error for object 0x7fb18f80d750:
incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
zsh: abort      ruby delegation_bench.rb
Disaster Strikes!
Pack Your Bags

• Download Ruby Source
  (https://github.com/ruby/ruby)
• Build
  ./configure && make

  (see ./configure   --help   for more)
Study the Map
• ./include/ruby/ruby.h
• ID => symbols
• VALUE => everything else
• rb_id2name => dump symbols in GDB
• rb_string_value_cstr => #to_s for GDB
• vm_call_method
Bring Your Gardener
               miniruby


• like ruby, only smaller
• lexer, parser, interpreter,VM/runtime
• core library classes
• make miniruby to build
Weapon of Choice
                  gdb


• gdb ./miniruby
• Set pre-run breakpoints
• Pass arguments to miniruby with “run”
• Watch it crash!
> gdb ./miniruby

...

(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
Reading symbols for shared libraries ++............................ done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000001100397198
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb)
> gdb ./miniruby

...

(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
Reading symbols for shared libraries ++............................ done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000001100397198
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb)
> gdb ./miniruby

...

(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
Reading symbols for shared libraries ++............................ done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000001100397198
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb)
(gdb) bt
#0 0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
#1 0x00007fff8e60e76d in szone_free_definite_size ()
#2 0x00007fff8e608898 in free ()
#3 0x000000010012f5dc in rb_free_method_entry [inlined] () at vm_method.c:155
#4 0x000000010012f5dc in rb_sweep_method_entry (pvm=0xb592caed) at...
#5 0x000000010004a00a in gc_lazy_sweep [inlined] () at gc.c:2107
#6 0x000000010004a00a in rb_newobj () at gc.c:1183
#7 0x000000010000caf4 in ary_alloc [inlined] () at array.c:301
#8 0x000000010000caf4 in ary_new (klass=4303833400, capa=3046355020) at...
#9 0x000000010000d165 in rb_ary_new2 [inlined] () at array.c:334
#10 0x000000010000d165 in rb_ary_new4 (n=0, elts=0x7fff5fbfee90) at array.c...
#11 0x000000010013288a in vm_yield_with_cfunc (th=0x100303e90, block=...
#12 0x000000010013dbb1 in rb_vm_invoke_proc (th=0x100303e90, proc=...
#13 0x000000010013bd90 in vm_call_bmethod [inlined] () at vm_insnhelper.c:433
#14 0x000000010013bd90 in vm_call_method (th=0x7fff5fbfef60,
cfp=0x7fff5fbfef60, num=8766224, blockptr=0x7fff5fbfef60,
flag=140734799802208, id=4298129040, me=0x10038ec90, recv=4303733520) at
vm_insnhelper.c:566
...

(gdb) p rb_string_value_cstr(4303733520)
(gdb) bt
#0 0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
#1 0x00007fff8e60e76d in szone_free_definite_size ()
#2 0x00007fff8e608898 in free ()
#3 0x000000010012f5dc in rb_free_method_entry [inlined] () at vm_method.c:155
#4 0x000000010012f5dc in rb_sweep_method_entry (pvm=0xb592caed) at...
#5 0x000000010004a00a in gc_lazy_sweep [inlined] () at gc.c:2107
#6 0x000000010004a00a in rb_newobj () at gc.c:1183
#7 0x000000010000caf4 in ary_alloc [inlined] () at array.c:301
#8 0x000000010000caf4 in ary_new (klass=4303833400, capa=3046355020) at...
#9 0x000000010000d165 in rb_ary_new2 [inlined] () at array.c:334
#10 0x000000010000d165 in rb_ary_new4 (n=0, elts=0x7fff5fbfee90) at array.c...
#11 0x000000010013288a in vm_yield_with_cfunc (th=0x100303e90, block=...
#12 0x000000010013dbb1 in rb_vm_invoke_proc (th=0x100303e90, proc=...
#13 0x000000010013bd90 in vm_call_bmethod [inlined] () at vm_insnhelper.c:433
#14 0x000000010013bd90 in vm_call_method (th=0x7fff5fbfef60,
cfp=0x7fff5fbfef60, num=8766224, blockptr=0x7fff5fbfef60,
flag=140734799802208, id=4298129040, me=0x10038ec90, recv=4303733520) at
vm_insnhelper.c:566
...

(gdb) p rb_string_value_cstr(4303733520)
(gdb) bt
#0 0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
#1 0x00007fff8e60e76d in szone_free_definite_size ()
#2 0x00007fff8e608898 in free ()
#3 0x000000010012f5dc in rb_free_method_entry [inlined] () at vm_method.c:155
#4 0x000000010012f5dc in rb_sweep_method_entry (pvm=0xb592caed) at...
#5 0x000000010004a00a in gc_lazy_sweep [inlined] () at gc.c:2107
#6 0x000000010004a00a in rb_newobj () at gc.c:1183
#7 0x000000010000caf4 in ary_alloc [inlined] () at array.c:301
#8 0x000000010000caf4 in ary_new (klass=4303833400, capa=3046355020) at...
#9 0x000000010000d165 in rb_ary_new2 [inlined] () at array.c:334
#10 0x000000010000d165 in rb_ary_new4 (n=0, elts=0x7fff5fbfee90) at array.c...
#11 0x000000010013288a in vm_yield_with_cfunc (th=0x100303e90, block=...
#12 0x000000010013dbb1 in rb_vm_invoke_proc (th=0x100303e90, proc=...
#13 0x000000010013bd90 in vm_call_bmethod [inlined] () at vm_insnhelper.c:433
#14 0x000000010013bd90 in vm_call_method (th=0x7fff5fbfef60,
cfp=0x7fff5fbfef60, num=8766224, blockptr=0x7fff5fbfef60,
flag=140734799802208, id=4298129040, me=0x10038ec90, recv=4303733520) at
vm_insnhelper.c:566
...

(gdb) p rb_string_value_cstr(4303733520)
(gdb) p rb_string_value_cstr(4303733520)
./bug.rb:7: [BUG] object allocation during garbage collection phase
ruby 1.9.3p286 (2012-10-12 revision 36243) [x86_64-darwin12.2.0]

-- Control frame information -----------------------------------------------
c:0009 p:0011 s:0021 b:0021 l:000888 d:000020 BLOCK ./bug.rb:7
c:0008 p:---- s:0019 b:0019 l:000018 d:000018 FINISH
c:0007 p:---- s:0017 b:0017 l:000016 d:000016 CFUNC :times
...
(gdb) p rb_string_value_cstr(4303733520)
./bug.rb:7: [BUG] object allocation during garbage collection phase
ruby 1.9.3p286 (2012-10-12 revision 36243) [x86_64-darwin12.2.0]

-- Control frame information -----------------------------------------------
c:0009 p:0011 s:0021 b:0021 l:000888 d:000020 BLOCK ./bug.rb:7
c:0008 p:---- s:0019 b:0019 l:000018 d:000018 FINISH
c:0007 p:---- s:0017 b:0017 l:000016 d:000016 CFUNC :times
...
(gdb) bt
#0 0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
#1 0x00007fff8e60e76d in szone_free_definite_size ()
#2 0x00007fff8e608898 in free ()
#3 0x000000010012f5dc in rb_free_method_entry [inlined] () at vm_method.c:155
#4 0x000000010012f5dc in rb_sweep_method_entry (pvm=0xb592caed) at...
#5 0x000000010004a00a in gc_lazy_sweep [inlined] () at gc.c:2107
#6 0x000000010004a00a in rb_newobj () at gc.c:1183
#7 0x000000010000caf4 in ary_alloc [inlined] () at array.c:301
#8 0x000000010000caf4 in ary_new (klass=4303833400, capa=3046355020) at...
#9 0x000000010000d165 in rb_ary_new2 [inlined] () at array.c:334
#10 0x000000010000d165 in rb_ary_new4 (n=0, elts=0x7fff5fbfee90) at array.c...
#11 0x000000010013288a in vm_yield_with_cfunc (th=0x100303e90, block=...
#12 0x000000010013dbb1 in rb_vm_invoke_proc (th=0x100303e90, proc=...
#13 0x000000010013bd90 in vm_call_bmethod [inlined] () at vm_insnhelper.c:433
#14 0x000000010013bd90 in vm_call_method (th=0x7fff5fbfef60,
cfp=0x7fff5fbfef60, num=8766224, blockptr=0x7fff5fbfef60,
flag=140734799802208, id=4298129040, me=0x10038ec90, recv=4303733520) at
vm_insnhelper.c:566
...
Call three methods 10,000 times
                     user     system      total        real
Pre-delegate   ruby(5919,0x7fff732a5180) malloc: *** error for object
0x7fb18f80d750: incorrect checksum for freed object - object was probably
modified after being freed.
*** set a breakpoint in malloc_error_break to debug
> gdb ./miniruby

...

(gdb) break malloc_error_break
Function "malloc_error_break" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (malloc_error_break) pending.
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
Reading symbols for shared libraries ++............................ done
Breakpoint 1 at 0x7fff8e607558
Pending breakpoint 1 - "malloc_error_break" resolved

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c908
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb)
> gdb ./miniruby

...

(gdb) break malloc_error_break
Function "malloc_error_break" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (malloc_error_break) pending.
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
Reading symbols for shared libraries ++............................ done
Breakpoint 1 at 0x7fff8e607558
Pending breakpoint 1 - "malloc_error_break" resolved

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c908
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb)
> gdb ./miniruby

...

(gdb) break malloc_error_break
Function "malloc_error_break" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (malloc_error_break) pending.
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
Reading symbols for shared libraries ++............................ done
Breakpoint 1 at 0x7fff8e607558
Pending breakpoint 1 - "malloc_error_break" resolved

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c908
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb)
> gdb ./miniruby

...

(gdb) break malloc_error_break
Function "malloc_error_break" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (malloc_error_break) pending.
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
Reading symbols for shared libraries ++............................ done
Breakpoint 1 at 0x7fff8e607558
Pending breakpoint 1 - "malloc_error_break" resolved

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c908
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb)
Advanced Weaponry
    MallocStackLoggingNoCompact


• man malloc
• Set environment variables to log the stack
    during allocations
• Run in GDB, use malloc_history to view
    stacks
•   CFLAGS=”-O0 -g” ./configure
(gdb) set environment MallocStackLoggingNoCompact=true
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
zsh(49630) malloc: recording malloc stacks to disk using standard recorder
zsh(49630) malloc: stack logging compaction turned off; size of log files on
disk can increase rapidly
...
Reading symbols for shared libraries ++............................ done
miniruby(49630) malloc: recording malloc stacks to disk using standard recorder
miniruby(49630) malloc: stack logging compaction turned off; size of log files
on disk can increase rapidly
miniruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch.
2JF4tB.index
miniruby(49630) malloc: stack logs being written into /tmp/stack-logs.
49630.miniruby.lZtwm8.index

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000001000000008
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb) set environment MallocStackLoggingNoCompact=true
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
zsh(49630) malloc: recording malloc stacks to disk using standard recorder
zsh(49630) malloc: stack logging compaction turned off; size of log files on
disk can increase rapidly
...
Reading symbols for shared libraries ++............................ done
miniruby(49630) malloc: recording malloc stacks to disk using standard recorder
miniruby(49630) malloc: stack logging compaction turned off; size of log files
on disk can increase rapidly
miniruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch.
2JF4tB.index
miniruby(49630) malloc: stack logs being written into /tmp/stack-logs.
49630.miniruby.lZtwm8.index

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000001000000008
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb) set environment MallocStackLoggingNoCompact=true
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
zsh(49630) malloc: recording malloc stacks to disk using standard recorder
zsh(49630) malloc: stack logging compaction turned off; size of log files on
disk can increase rapidly
...
Reading symbols for shared libraries ++............................ done
miniruby(49630) malloc: recording malloc stacks to disk using standard recorder
miniruby(49630) malloc: stack logging compaction turned off; size of log files
on disk can increase rapidly
miniruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch.
2JF4tB.index
miniruby(49630) malloc: stack logs being written into /tmp/stack-logs.
49630.miniruby.lZtwm8.index

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000001000000008
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb) set environment MallocStackLoggingNoCompact=true
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
zsh(49630) malloc: recording malloc stacks to disk using standard recorder
zsh(49630) malloc: stack logging compaction turned off; size of log files on
disk can increase rapidly
...
Reading symbols for shared libraries ++............................ done
miniruby(49630) malloc: recording malloc stacks to disk using standard recorder
miniruby(49630) malloc: stack logging compaction turned off; size of log files
on disk can increase rapidly
miniruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch.
2JF4tB.index
miniruby(49630) malloc: stack logs being written into /tmp/stack-logs.
49630.miniruby.lZtwm8.index

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000001000000008
0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
(gdb) bt
#0 0x00007fff8e611cfb   in   tiny_free_list_remove_ptr ()
#1 0x00007fff8e60e76d   in   szone_free_definite_size ()
#2 0x00007fff8e608898   in   free ()
#3 0x000000010006f6cc   in   vm_xfree (objspace=0x10081c400, ptr=0x1004918b0)
at gc.c:830
#4 0x000000010006fa76   in ruby_xfree (x=0x1004918b0) at gc.c:894
...
> malloc_history 49630 0x1004918b0
malloc_history Report Version: 2.0
Process:         miniruby [49630]
...
ALLOC 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main |
ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
rb_class_new_instance | rb_obj_call_init | rb_funcall2 | rb_call | rb_call0 |
vm_call0 | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc |
call_cfunc | method_proc | rb_iterate | mlambda | rb_funcall | rb_call |
rb_call0 | vm_call0 | call_cfunc | proc_lambda | rb_block_lambda | proc_new |
rb_vm_make_proc | rb_proc_alloc | ruby_xmalloc | vm_xmalloc | malloc |
malloc_zone_malloc
----
FREE 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main |
ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_bmethod | rb_vm_invoke_proc
| invoke_block_from_c | vm_yield_with_cfunc | bmcall | rb_method_call |
rb_vm_call | vm_call0 | rb_threadptr_execute_interrupts |
rb_threadptr_execute_interrupts_common | rb_gc_finalize_deferred |
finalize_deferred | finalize_list | run_final | proc_free | ruby_xfree |
vm_xfree | free
> malloc_history 49630 0x1004918b0
malloc_history Report Version: 2.0
Process:         miniruby [49630]
...
ALLOC 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main |
ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
rb_class_new_instance | rb_obj_call_init | rb_funcall2 | rb_call | rb_call0 |
vm_call0 | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc |
call_cfunc | method_proc | rb_iterate | mlambda | rb_funcall | rb_call |
rb_call0 | vm_call0 | call_cfunc | proc_lambda | rb_block_lambda | proc_new |
rb_vm_make_proc | rb_proc_alloc | ruby_xmalloc | vm_xmalloc | malloc |
malloc_zone_malloc
----
FREE 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main |
ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_bmethod | rb_vm_invoke_proc
| invoke_block_from_c | vm_yield_with_cfunc | bmcall | rb_method_call |
rb_vm_call | vm_call0 | rb_threadptr_execute_interrupts |
rb_threadptr_execute_interrupts_common | rb_gc_finalize_deferred |
finalize_deferred | finalize_list | run_final | proc_free | ruby_xfree |
vm_xfree | free
> malloc_history 49630 0x1004918b0
malloc_history Report Version: 2.0
Process:         miniruby [49630]
...
ALLOC 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main |
ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
rb_class_new_instance | rb_obj_call_init | rb_funcall2 | rb_call | rb_call0 |
vm_call0 | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc |
call_cfunc | method_proc | rb_iterate | mlambda | rb_funcall | rb_call |
rb_call0 | vm_call0 | call_cfunc | proc_lambda | rb_block_lambda | proc_new |
rb_vm_make_proc | rb_proc_alloc | ruby_xmalloc | vm_xmalloc | malloc |
malloc_zone_malloc
----
FREE 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main |
ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_bmethod | rb_vm_invoke_proc
| invoke_block_from_c | vm_yield_with_cfunc | bmcall | rb_method_call |
rb_vm_call | vm_call0 | rb_threadptr_execute_interrupts |
rb_threadptr_execute_interrupts_common | rb_gc_finalize_deferred |
finalize_deferred | finalize_list | run_final | proc_free | ruby_xfree |
vm_xfree | free
> malloc_history 49630 0x1004918b0
malloc_history Report Version: 2.0
Process:         miniruby [49630]
...
ALLOC 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main |
ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
rb_class_new_instance | rb_obj_call_init | rb_funcall2 | rb_call | rb_call0 |
vm_call0 | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc |
call_cfunc | method_proc | rb_iterate | mlambda | rb_funcall | rb_call |
rb_call0 | vm_call0 | call_cfunc | proc_lambda | rb_block_lambda | proc_new |
rb_vm_make_proc | rb_proc_alloc | ruby_xmalloc | vm_xmalloc | malloc |
malloc_zone_malloc
----
FREE 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main |
ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c |
vm_exec | vm_exec_core | vm_call_method | vm_call_bmethod | rb_vm_invoke_proc
| invoke_block_from_c | vm_yield_with_cfunc | bmcall | rb_method_call |
rb_vm_call | vm_call0 | rb_threadptr_execute_interrupts |
rb_threadptr_execute_interrupts_common | rb_gc_finalize_deferred |
finalize_deferred | finalize_list | run_final | proc_free | ruby_xfree |
vm_xfree | free
BFGmalloc

libgmalloc.dylib -- (Guard Malloc),
  an aggressive debugging malloc
              library
BFGmalloc

malloc



gmalloc
BFGmalloc

malloc



gmalloc
BFGmalloc

malloc



gmalloc
BFGmalloc

malloc



gmalloc
BFGmalloc

malloc



gmalloc
BFGmalloc

malloc



gmalloc
BFGmalloc

malloc



gmalloc
(gdb) set environment MallocStackLoggingNoCompact=true
(gdb) set environment DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
GuardMalloc[zsh-50147]: recording malloc stacks to disk using standard recorder
GuardMalloc[zsh-50147]: stack logging compaction turned off; size of log files
on disk can increase rapidly
...
(gdb) set environment MallocStackLoggingNoCompact=true
(gdb) set environment DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
GuardMalloc[zsh-50147]: recording malloc stacks to disk using standard recorder
GuardMalloc[zsh-50147]: stack logging compaction turned off; size of log files
on disk can increase rapidly
...
(gdb) set environment MallocStackLoggingNoCompact=true
(gdb) set environment DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib
(gdb) run ./bug.rb
Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb
GuardMalloc[zsh-50147]: recording malloc stacks to disk using standard recorder
GuardMalloc[zsh-50147]: stack logging compaction turned off; size of log files
on disk can increase rapidly
...
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000107203fe4
0x0000000100208b3c in rb_thread_mark (ptr=0x10085fce0) at vm.c:1733
1733!   !  !    if (cfp->me) ((rb_method_entry_t *)cfp->me)->mark = 1;
(gdb) p cfp->me
$1 = (rb_method_entry_t *) 0x107203fe0
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000107203fe4
0x0000000100208b3c in rb_thread_mark (ptr=0x10085fce0) at vm.c:1733
1733!   !  !    if (cfp->me) ((rb_method_entry_t *)cfp->me)->mark = 1;
(gdb) p cfp->me
$1 = (rb_method_entry_t *) 0x107203fe0
> malloc_history 50147 0x107203fe0
malloc_history Report Version: 2.0
Process:         miniruby [50147]
...
FREE 0x107203fe0-0x107203fff [size=32]: thread_7fff732a5180 |start | main |
ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec |
vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes |
rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core
| vm_call_method | vm_call_bmethod | rb_vm_invoke_proc | invoke_block_from_c |
vm_yield_with_cfunc | bmcall | rb_method_call | rb_vm_call | vm_call0 |
call_cfunc | rb_str_reverse | rb_str_new_with_class | str_new | str_alloc |
rb_newobj | gc_lazy_sweep | lazy_sweep | slot_sweep | obj_free | rb_free_m_table
| st_foreach | free_method_entry_i | rb_free_method_entry | ruby_xfree |
vm_xfree | GMfree | GMmalloc_zone_free
> malloc_history 50147 0x107203fe0
malloc_history Report Version: 2.0
Process:         miniruby [50147]
...
FREE 0x107203fe0-0x107203fff [size=32]: thread_7fff732a5180 |start | main |
ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main |
vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc |
int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec |
vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes |
rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core
| vm_call_method | vm_call_bmethod | rb_vm_invoke_proc | invoke_block_from_c |
vm_yield_with_cfunc | bmcall | rb_method_call | rb_vm_call | vm_call0 |
call_cfunc | rb_str_reverse | rb_str_new_with_class | str_new | str_alloc |
rb_newobj | gc_lazy_sweep | lazy_sweep | slot_sweep | obj_free | rb_free_m_table
| st_foreach | free_method_entry_i | rb_free_method_entry | ruby_xfree |
vm_xfree | GMfree | GMmalloc_zone_free
https://bugs.ruby-lang.org/issues/6171
Questions?

     Joshua Ballanco
   @manhattanmetric
https://github.com/jballanc

More Related Content

What's hot

A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
旻琦 潘
 
Sdl Basic
Sdl BasicSdl Basic
Sdl Basic
roberto viola
 
Advanced python
Advanced pythonAdvanced python
Advanced python
EU Edge
 
JavaScript for beginners
JavaScript for beginners JavaScript for beginners
JavaScript for beginners
Shahrukh Ali Khan
 
ES2015 workflows
ES2015 workflowsES2015 workflows
ES2015 workflows
Jarrod Overson
 
ES6 and BEYOND
ES6 and BEYONDES6 and BEYOND
ES6 and BEYOND
Brian Patterson
 
(Parameterized) Roles
(Parameterized) Roles(Parameterized) Roles
(Parameterized) Roles
sartak
 
Exhibition of Atrocity
Exhibition of AtrocityExhibition of Atrocity
Exhibition of Atrocity
Michael Pirnat
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
Dr Nic Williams
 
Advanced Python, Part 2
Advanced Python, Part 2Advanced Python, Part 2
Advanced Python, Part 2
Zaar Hai
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
Ingvar Stepanyan
 
Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8
Wilson Su
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
Visual Engineering
 
JRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMJRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVM
Charles Nutter
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
kwatch
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder Ruby
Nick Sieger
 
JavaScript on the GPU
JavaScript on the GPUJavaScript on the GPU
JavaScript on the GPU
Jarred Nicholls
 
Vim Hacks
Vim HacksVim Hacks
Vim Hacks
Lin Yo-An
 
Don't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax TreesDon't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax Trees
Jamund Ferguson
 
Visual Studio를 이용한 어셈블리어 학습 part 2
Visual Studio를 이용한 어셈블리어 학습 part 2Visual Studio를 이용한 어셈블리어 학습 part 2
Visual Studio를 이용한 어셈블리어 학습 part 2
YEONG-CHEON YOU
 

What's hot (20)

A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Sdl Basic
Sdl BasicSdl Basic
Sdl Basic
 
Advanced python
Advanced pythonAdvanced python
Advanced python
 
JavaScript for beginners
JavaScript for beginners JavaScript for beginners
JavaScript for beginners
 
ES2015 workflows
ES2015 workflowsES2015 workflows
ES2015 workflows
 
ES6 and BEYOND
ES6 and BEYONDES6 and BEYOND
ES6 and BEYOND
 
(Parameterized) Roles
(Parameterized) Roles(Parameterized) Roles
(Parameterized) Roles
 
Exhibition of Atrocity
Exhibition of AtrocityExhibition of Atrocity
Exhibition of Atrocity
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
 
Advanced Python, Part 2
Advanced Python, Part 2Advanced Python, Part 2
Advanced Python, Part 2
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
 
Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
JRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVMJRuby 9000 - Optimizing Above the JVM
JRuby 9000 - Optimizing Above the JVM
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
 
JRuby @ Boulder Ruby
JRuby @ Boulder RubyJRuby @ Boulder Ruby
JRuby @ Boulder Ruby
 
JavaScript on the GPU
JavaScript on the GPUJavaScript on the GPU
JavaScript on the GPU
 
Vim Hacks
Vim HacksVim Hacks
Vim Hacks
 
Don't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax TreesDon't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax Trees
 
Visual Studio를 이용한 어셈블리어 학습 part 2
Visual Studio를 이용한 어셈블리어 학습 part 2Visual Studio를 이용한 어셈블리어 학습 part 2
Visual Studio를 이용한 어셈블리어 학습 part 2
 

Viewers also liked

MacRuby: What is it? and why should you care?
MacRuby: What is it? and why should you care?MacRuby: What is it? and why should you care?
MacRuby: What is it? and why should you care?
Joshua Ballanco
 
A Tale of Two Rubies
A Tale of Two RubiesA Tale of Two Rubies
A Tale of Two Rubies
Joshua Ballanco
 
MacRuby for Fun and Profit
MacRuby for Fun and ProfitMacRuby for Fun and Profit
MacRuby for Fun and Profit
Joshua Ballanco
 
RubyMotion: Under the Hood
RubyMotion: Under the HoodRubyMotion: Under the Hood
RubyMotion: Under the Hood
Joshua Ballanco
 
Debugging RubyMotion
Debugging RubyMotionDebugging RubyMotion
Debugging RubyMotion
Joshua Ballanco
 
Getting Your Ruby EGOT
Getting Your Ruby EGOTGetting Your Ruby EGOT
Getting Your Ruby EGOT
Joshua Ballanco
 
5分でできる U S T配信(保存用)
5分でできる U S T配信(保存用)5分でできる U S T配信(保存用)
5分でできる U S T配信(保存用)Hiroaki Kobayashi
 
Keeping ruby reasonable
Keeping ruby reasonableKeeping ruby reasonable
Keeping ruby reasonable
Joshua Ballanco
 
Ruby memory model
Ruby memory modelRuby memory model
Ruby memory model
Hari Krishnan‎
 

Viewers also liked (9)

MacRuby: What is it? and why should you care?
MacRuby: What is it? and why should you care?MacRuby: What is it? and why should you care?
MacRuby: What is it? and why should you care?
 
A Tale of Two Rubies
A Tale of Two RubiesA Tale of Two Rubies
A Tale of Two Rubies
 
MacRuby for Fun and Profit
MacRuby for Fun and ProfitMacRuby for Fun and Profit
MacRuby for Fun and Profit
 
RubyMotion: Under the Hood
RubyMotion: Under the HoodRubyMotion: Under the Hood
RubyMotion: Under the Hood
 
Debugging RubyMotion
Debugging RubyMotionDebugging RubyMotion
Debugging RubyMotion
 
Getting Your Ruby EGOT
Getting Your Ruby EGOTGetting Your Ruby EGOT
Getting Your Ruby EGOT
 
5分でできる U S T配信(保存用)
5分でできる U S T配信(保存用)5分でできる U S T配信(保存用)
5分でできる U S T配信(保存用)
 
Keeping ruby reasonable
Keeping ruby reasonableKeeping ruby reasonable
Keeping ruby reasonable
 
Ruby memory model
Ruby memory modelRuby memory model
Ruby memory model
 

Similar to There and Back Again

JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015
Charles Nutter
 
Crash_Report_Mechanism_In_Tizen
Crash_Report_Mechanism_In_TizenCrash_Report_Mechanism_In_Tizen
Crash_Report_Mechanism_In_Tizen
Lex Yu
 
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
David Beazley (Dabeaz LLC)
 
Use Ruby GC in full..
Use Ruby GC in full..Use Ruby GC in full..
Use Ruby GC in full..
Alex Mercer
 
Valgrind
ValgrindValgrind
Valgrind
aidanshribman
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: Serversideness
WebExpo
 
Rubinius 1.0 and more!
Rubinius 1.0 and more!Rubinius 1.0 and more!
Rubinius 1.0 and more!
evanphx
 
Digging for Android Kernel Bugs
Digging for Android Kernel BugsDigging for Android Kernel Bugs
Digging for Android Kernel Bugs
Jiahong Fang
 
Android RenderScript on LLVM
Android RenderScript on LLVMAndroid RenderScript on LLVM
Android RenderScript on LLVM
John Lee
 
Практический опыт профайлинга и оптимизации производительности Ruby-приложений
Практический опыт профайлинга и оптимизации производительности Ruby-приложенийПрактический опыт профайлинга и оптимизации производительности Ruby-приложений
Практический опыт профайлинга и оптимизации производительности Ruby-приложений
Olga Lavrentieva
 
Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplos
vinibaggio
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
Emanuele DelBono
 
PGCon 2014 - What Do You Mean my Database Server Core Dumped? - How to Inspec...
PGCon 2014 - What Do You Mean my Database Server Core Dumped? - How to Inspec...PGCon 2014 - What Do You Mean my Database Server Core Dumped? - How to Inspec...
PGCon 2014 - What Do You Mean my Database Server Core Dumped? - How to Inspec...
Faisal Akber
 
Run Node Run
Run Node RunRun Node Run
Run Node Run
Kevin Swiber
 
Bypassing ASLR Exploiting CVE 2015-7545
Bypassing ASLR Exploiting CVE 2015-7545Bypassing ASLR Exploiting CVE 2015-7545
Bypassing ASLR Exploiting CVE 2015-7545
Kernel TLV
 
Playing 44CON CTF for fun and profit
Playing 44CON CTF for fun and profitPlaying 44CON CTF for fun and profit
Playing 44CON CTF for fun and profit
44CON
 
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
chen yuki
 
mtl_rubykaigi
mtl_rubykaigimtl_rubykaigi
mtl_rubykaigi
Hirotomo Oi
 
Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)
Ontico
 
Writing Metasploit Plugins
Writing Metasploit PluginsWriting Metasploit Plugins
Writing Metasploit Plugins
amiable_indian
 

Similar to There and Back Again (20)

JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015JRuby 9000 - Taipei Ruby User's Group 2015
JRuby 9000 - Taipei Ruby User's Group 2015
 
Crash_Report_Mechanism_In_Tizen
Crash_Report_Mechanism_In_TizenCrash_Report_Mechanism_In_Tizen
Crash_Report_Mechanism_In_Tizen
 
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
 
Use Ruby GC in full..
Use Ruby GC in full..Use Ruby GC in full..
Use Ruby GC in full..
 
Valgrind
ValgrindValgrind
Valgrind
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: Serversideness
 
Rubinius 1.0 and more!
Rubinius 1.0 and more!Rubinius 1.0 and more!
Rubinius 1.0 and more!
 
Digging for Android Kernel Bugs
Digging for Android Kernel BugsDigging for Android Kernel Bugs
Digging for Android Kernel Bugs
 
Android RenderScript on LLVM
Android RenderScript on LLVMAndroid RenderScript on LLVM
Android RenderScript on LLVM
 
Практический опыт профайлинга и оптимизации производительности Ruby-приложений
Практический опыт профайлинга и оптимизации производительности Ruby-приложенийПрактический опыт профайлинга и оптимизации производительности Ruby-приложений
Практический опыт профайлинга и оптимизации производительности Ruby-приложений
 
Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplos
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
PGCon 2014 - What Do You Mean my Database Server Core Dumped? - How to Inspec...
PGCon 2014 - What Do You Mean my Database Server Core Dumped? - How to Inspec...PGCon 2014 - What Do You Mean my Database Server Core Dumped? - How to Inspec...
PGCon 2014 - What Do You Mean my Database Server Core Dumped? - How to Inspec...
 
Run Node Run
Run Node RunRun Node Run
Run Node Run
 
Bypassing ASLR Exploiting CVE 2015-7545
Bypassing ASLR Exploiting CVE 2015-7545Bypassing ASLR Exploiting CVE 2015-7545
Bypassing ASLR Exploiting CVE 2015-7545
 
Playing 44CON CTF for fun and profit
Playing 44CON CTF for fun and profitPlaying 44CON CTF for fun and profit
Playing 44CON CTF for fun and profit
 
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
 
mtl_rubykaigi
mtl_rubykaigimtl_rubykaigi
mtl_rubykaigi
 
Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)
 
Writing Metasploit Plugins
Writing Metasploit PluginsWriting Metasploit Plugins
Writing Metasploit Plugins
 

Recently uploaded

Introducing BoxLang : A new JVM language for productivity and modularity!
Introducing BoxLang : A new JVM language for productivity and modularity!Introducing BoxLang : A new JVM language for productivity and modularity!
Introducing BoxLang : A new JVM language for productivity and modularity!
Ortus Solutions, Corp
 
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectorsConnector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
DianaGray10
 
inQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
inQuba Webinar Mastering Customer Journey Management with Dr Graham HillinQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
inQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
LizaNolte
 
LF Energy Webinar: Carbon Data Specifications: Mechanisms to Improve Data Acc...
LF Energy Webinar: Carbon Data Specifications: Mechanisms to Improve Data Acc...LF Energy Webinar: Carbon Data Specifications: Mechanisms to Improve Data Acc...
LF Energy Webinar: Carbon Data Specifications: Mechanisms to Improve Data Acc...
DanBrown980551
 
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
AlexanderRichford
 
ScyllaDB Tablets: Rethinking Replication
ScyllaDB Tablets: Rethinking ReplicationScyllaDB Tablets: Rethinking Replication
ScyllaDB Tablets: Rethinking Replication
ScyllaDB
 
QA or the Highway - Component Testing: Bridging the gap between frontend appl...
QA or the Highway - Component Testing: Bridging the gap between frontend appl...QA or the Highway - Component Testing: Bridging the gap between frontend appl...
QA or the Highway - Component Testing: Bridging the gap between frontend appl...
zjhamm304
 
"Scaling RAG Applications to serve millions of users", Kevin Goedecke
"Scaling RAG Applications to serve millions of users",  Kevin Goedecke"Scaling RAG Applications to serve millions of users",  Kevin Goedecke
"Scaling RAG Applications to serve millions of users", Kevin Goedecke
Fwdays
 
Christine's Product Research Presentation.pptx
Christine's Product Research Presentation.pptxChristine's Product Research Presentation.pptx
Christine's Product Research Presentation.pptx
christinelarrosa
 
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptxPRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
christinelarrosa
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
Fwdays
 
GlobalLogic Java Community Webinar #18 “How to Improve Web Application Perfor...
GlobalLogic Java Community Webinar #18 “How to Improve Web Application Perfor...GlobalLogic Java Community Webinar #18 “How to Improve Web Application Perfor...
GlobalLogic Java Community Webinar #18 “How to Improve Web Application Perfor...
GlobalLogic Ukraine
 
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
Jason Yip
 
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
Fwdays
 
A Deep Dive into ScyllaDB's Architecture
A Deep Dive into ScyllaDB's ArchitectureA Deep Dive into ScyllaDB's Architecture
A Deep Dive into ScyllaDB's Architecture
ScyllaDB
 
Northern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
Northern Engraving | Modern Metal Trim, Nameplates and Appliance PanelsNorthern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
Northern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
Northern Engraving
 
Discover the Unseen: Tailored Recommendation of Unwatched Content
Discover the Unseen: Tailored Recommendation of Unwatched ContentDiscover the Unseen: Tailored Recommendation of Unwatched Content
Discover the Unseen: Tailored Recommendation of Unwatched Content
ScyllaDB
 
Must Know Postgres Extension for DBA and Developer during Migration
Must Know Postgres Extension for DBA and Developer during MigrationMust Know Postgres Extension for DBA and Developer during Migration
Must Know Postgres Extension for DBA and Developer during Migration
Mydbops
 
"NATO Hackathon Winner: AI-Powered Drug Search", Taras Kloba
"NATO Hackathon Winner: AI-Powered Drug Search",  Taras Kloba"NATO Hackathon Winner: AI-Powered Drug Search",  Taras Kloba
"NATO Hackathon Winner: AI-Powered Drug Search", Taras Kloba
Fwdays
 
Leveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and StandardsLeveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and Standards
Neo4j
 

Recently uploaded (20)

Introducing BoxLang : A new JVM language for productivity and modularity!
Introducing BoxLang : A new JVM language for productivity and modularity!Introducing BoxLang : A new JVM language for productivity and modularity!
Introducing BoxLang : A new JVM language for productivity and modularity!
 
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectorsConnector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
 
inQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
inQuba Webinar Mastering Customer Journey Management with Dr Graham HillinQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
inQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
 
LF Energy Webinar: Carbon Data Specifications: Mechanisms to Improve Data Acc...
LF Energy Webinar: Carbon Data Specifications: Mechanisms to Improve Data Acc...LF Energy Webinar: Carbon Data Specifications: Mechanisms to Improve Data Acc...
LF Energy Webinar: Carbon Data Specifications: Mechanisms to Improve Data Acc...
 
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
 
ScyllaDB Tablets: Rethinking Replication
ScyllaDB Tablets: Rethinking ReplicationScyllaDB Tablets: Rethinking Replication
ScyllaDB Tablets: Rethinking Replication
 
QA or the Highway - Component Testing: Bridging the gap between frontend appl...
QA or the Highway - Component Testing: Bridging the gap between frontend appl...QA or the Highway - Component Testing: Bridging the gap between frontend appl...
QA or the Highway - Component Testing: Bridging the gap between frontend appl...
 
"Scaling RAG Applications to serve millions of users", Kevin Goedecke
"Scaling RAG Applications to serve millions of users",  Kevin Goedecke"Scaling RAG Applications to serve millions of users",  Kevin Goedecke
"Scaling RAG Applications to serve millions of users", Kevin Goedecke
 
Christine's Product Research Presentation.pptx
Christine's Product Research Presentation.pptxChristine's Product Research Presentation.pptx
Christine's Product Research Presentation.pptx
 
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptxPRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
 
GlobalLogic Java Community Webinar #18 “How to Improve Web Application Perfor...
GlobalLogic Java Community Webinar #18 “How to Improve Web Application Perfor...GlobalLogic Java Community Webinar #18 “How to Improve Web Application Perfor...
GlobalLogic Java Community Webinar #18 “How to Improve Web Application Perfor...
 
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
 
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
 
A Deep Dive into ScyllaDB's Architecture
A Deep Dive into ScyllaDB's ArchitectureA Deep Dive into ScyllaDB's Architecture
A Deep Dive into ScyllaDB's Architecture
 
Northern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
Northern Engraving | Modern Metal Trim, Nameplates and Appliance PanelsNorthern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
Northern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
 
Discover the Unseen: Tailored Recommendation of Unwatched Content
Discover the Unseen: Tailored Recommendation of Unwatched ContentDiscover the Unseen: Tailored Recommendation of Unwatched Content
Discover the Unseen: Tailored Recommendation of Unwatched Content
 
Must Know Postgres Extension for DBA and Developer during Migration
Must Know Postgres Extension for DBA and Developer during MigrationMust Know Postgres Extension for DBA and Developer during Migration
Must Know Postgres Extension for DBA and Developer during Migration
 
"NATO Hackathon Winner: AI-Powered Drug Search", Taras Kloba
"NATO Hackathon Winner: AI-Powered Drug Search",  Taras Kloba"NATO Hackathon Winner: AI-Powered Drug Search",  Taras Kloba
"NATO Hackathon Winner: AI-Powered Drug Search", Taras Kloba
 
Leveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and StandardsLeveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and Standards
 

There and Back Again

  • 1. There and Back Again – or – How I Set out to Benchmark an Algorithm and Ended Up Fixing Ruby
  • 2. About Me Name: Joshua Ballanco
  • 6. WARNING This is an ADVANCED presentation. While you do not need to be an expert on the inner workings of C Ruby, this talk does presume you are familiar with concepts such as pointers, memory allocation, and pages (no, not book pages, memory pages). If you are prone to motion sickness or become nauseous at the sight of hexadecimal memory addresses, this talk may not be for you.
  • 7. Prelude: How can I contribute to Ruby?
  • 8. Prelude: How can I contribute to Ruby? Use It!
  • 9. 4 Rs of Bug Reporting • Reproduce • Report • Reduce • Regress
  • 10. Reproduce It! • Can you make the bug occur every time? most of the time? some of the time? • .irbrc, .gemrc, Other rc files • Environment and Environment Variables • rvm/rbenv • Ask a friend
  • 11. Report It! • Ruby Bug Tracker: http://bugs.ruby-lang.org/ • All steps to reproduce, bonus points for attachments • Ruby Version • Crash log (hint: look in Console.app)
  • 12.
  • 13. Reduce It! • Eliminate libraries • Simple scripts are best • Shrink code (5 or fewer lines is ideal)
  • 14. Regress It! • Try different Ruby versions • Better: try different Ruby releases • Best: git bisect! • Bonus: try different build settings
  • 15. 5 Rs of Bug Reporting • Reproduce • Report • Reduce • Regress • Repair!
  • 16. A long time ago in a faraway land...
  • 17. A long time ago in a faraway land...
  • 18. A long time ago in a faraway land...
  • 19. A long time ago in a faraway land...
  • 20. A long time ago in a faraway land...
  • 21. A long time ago in a faraway land... for full backstory, see: http://blogs.burnsidedigital.com/
  • 22. Disaster Strikes! > ruby delegation_bench.rb Call one method user system total real Pre-delegate 4.940000 0.020000 4.960000 ( 4.954945) Post-delegate 0.060000 0.000000 0.060000 ( 0.060528) On Demand 0.010000 0.000000 0.010000 ( 0.010604) Reversible 0.110000 0.000000 0.110000 ( 0.101494) Call one method 100 times ... Call three methods 100 times user system total real Pre-delegate 5.640000 0.000000 5.640000 ( 5.640255) Post-delegate 0.980000 0.000000 0.980000 ( 0.975919) On Demand 1.210000 0.000000 1.210000 ( 1.205214) Reversible 1.020000 0.000000 1.020000 ( 1.027759) Call three methods 10,000 times user system total real Pre-delegate ruby(5919,0x7fff732a5180) malloc: *** error for object 0x7fb18f80d750: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug zsh: abort ruby delegation_bench.rb
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33. Pack Your Bags • Download Ruby Source (https://github.com/ruby/ruby) • Build ./configure && make (see ./configure --help for more)
  • 34. Study the Map • ./include/ruby/ruby.h • ID => symbols • VALUE => everything else • rb_id2name => dump symbols in GDB • rb_string_value_cstr => #to_s for GDB • vm_call_method
  • 35. Bring Your Gardener miniruby • like ruby, only smaller • lexer, parser, interpreter,VM/runtime • core library classes • make miniruby to build
  • 36. Weapon of Choice gdb • gdb ./miniruby • Set pre-run breakpoints • Pass arguments to miniruby with “run” • Watch it crash!
  • 37. > gdb ./miniruby ... (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb Reading symbols for shared libraries ++............................ done Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000001100397198 0x00007fff8e611cfb in tiny_free_list_remove_ptr () (gdb)
  • 38. > gdb ./miniruby ... (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb Reading symbols for shared libraries ++............................ done Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000001100397198 0x00007fff8e611cfb in tiny_free_list_remove_ptr () (gdb)
  • 39. > gdb ./miniruby ... (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb Reading symbols for shared libraries ++............................ done Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000001100397198 0x00007fff8e611cfb in tiny_free_list_remove_ptr () (gdb)
  • 40. (gdb) bt #0 0x00007fff8e611cfb in tiny_free_list_remove_ptr () #1 0x00007fff8e60e76d in szone_free_definite_size () #2 0x00007fff8e608898 in free () #3 0x000000010012f5dc in rb_free_method_entry [inlined] () at vm_method.c:155 #4 0x000000010012f5dc in rb_sweep_method_entry (pvm=0xb592caed) at... #5 0x000000010004a00a in gc_lazy_sweep [inlined] () at gc.c:2107 #6 0x000000010004a00a in rb_newobj () at gc.c:1183 #7 0x000000010000caf4 in ary_alloc [inlined] () at array.c:301 #8 0x000000010000caf4 in ary_new (klass=4303833400, capa=3046355020) at... #9 0x000000010000d165 in rb_ary_new2 [inlined] () at array.c:334 #10 0x000000010000d165 in rb_ary_new4 (n=0, elts=0x7fff5fbfee90) at array.c... #11 0x000000010013288a in vm_yield_with_cfunc (th=0x100303e90, block=... #12 0x000000010013dbb1 in rb_vm_invoke_proc (th=0x100303e90, proc=... #13 0x000000010013bd90 in vm_call_bmethod [inlined] () at vm_insnhelper.c:433 #14 0x000000010013bd90 in vm_call_method (th=0x7fff5fbfef60, cfp=0x7fff5fbfef60, num=8766224, blockptr=0x7fff5fbfef60, flag=140734799802208, id=4298129040, me=0x10038ec90, recv=4303733520) at vm_insnhelper.c:566 ... (gdb) p rb_string_value_cstr(4303733520)
  • 41. (gdb) bt #0 0x00007fff8e611cfb in tiny_free_list_remove_ptr () #1 0x00007fff8e60e76d in szone_free_definite_size () #2 0x00007fff8e608898 in free () #3 0x000000010012f5dc in rb_free_method_entry [inlined] () at vm_method.c:155 #4 0x000000010012f5dc in rb_sweep_method_entry (pvm=0xb592caed) at... #5 0x000000010004a00a in gc_lazy_sweep [inlined] () at gc.c:2107 #6 0x000000010004a00a in rb_newobj () at gc.c:1183 #7 0x000000010000caf4 in ary_alloc [inlined] () at array.c:301 #8 0x000000010000caf4 in ary_new (klass=4303833400, capa=3046355020) at... #9 0x000000010000d165 in rb_ary_new2 [inlined] () at array.c:334 #10 0x000000010000d165 in rb_ary_new4 (n=0, elts=0x7fff5fbfee90) at array.c... #11 0x000000010013288a in vm_yield_with_cfunc (th=0x100303e90, block=... #12 0x000000010013dbb1 in rb_vm_invoke_proc (th=0x100303e90, proc=... #13 0x000000010013bd90 in vm_call_bmethod [inlined] () at vm_insnhelper.c:433 #14 0x000000010013bd90 in vm_call_method (th=0x7fff5fbfef60, cfp=0x7fff5fbfef60, num=8766224, blockptr=0x7fff5fbfef60, flag=140734799802208, id=4298129040, me=0x10038ec90, recv=4303733520) at vm_insnhelper.c:566 ... (gdb) p rb_string_value_cstr(4303733520)
  • 42. (gdb) bt #0 0x00007fff8e611cfb in tiny_free_list_remove_ptr () #1 0x00007fff8e60e76d in szone_free_definite_size () #2 0x00007fff8e608898 in free () #3 0x000000010012f5dc in rb_free_method_entry [inlined] () at vm_method.c:155 #4 0x000000010012f5dc in rb_sweep_method_entry (pvm=0xb592caed) at... #5 0x000000010004a00a in gc_lazy_sweep [inlined] () at gc.c:2107 #6 0x000000010004a00a in rb_newobj () at gc.c:1183 #7 0x000000010000caf4 in ary_alloc [inlined] () at array.c:301 #8 0x000000010000caf4 in ary_new (klass=4303833400, capa=3046355020) at... #9 0x000000010000d165 in rb_ary_new2 [inlined] () at array.c:334 #10 0x000000010000d165 in rb_ary_new4 (n=0, elts=0x7fff5fbfee90) at array.c... #11 0x000000010013288a in vm_yield_with_cfunc (th=0x100303e90, block=... #12 0x000000010013dbb1 in rb_vm_invoke_proc (th=0x100303e90, proc=... #13 0x000000010013bd90 in vm_call_bmethod [inlined] () at vm_insnhelper.c:433 #14 0x000000010013bd90 in vm_call_method (th=0x7fff5fbfef60, cfp=0x7fff5fbfef60, num=8766224, blockptr=0x7fff5fbfef60, flag=140734799802208, id=4298129040, me=0x10038ec90, recv=4303733520) at vm_insnhelper.c:566 ... (gdb) p rb_string_value_cstr(4303733520)
  • 43. (gdb) p rb_string_value_cstr(4303733520) ./bug.rb:7: [BUG] object allocation during garbage collection phase ruby 1.9.3p286 (2012-10-12 revision 36243) [x86_64-darwin12.2.0] -- Control frame information ----------------------------------------------- c:0009 p:0011 s:0021 b:0021 l:000888 d:000020 BLOCK ./bug.rb:7 c:0008 p:---- s:0019 b:0019 l:000018 d:000018 FINISH c:0007 p:---- s:0017 b:0017 l:000016 d:000016 CFUNC :times ...
  • 44. (gdb) p rb_string_value_cstr(4303733520) ./bug.rb:7: [BUG] object allocation during garbage collection phase ruby 1.9.3p286 (2012-10-12 revision 36243) [x86_64-darwin12.2.0] -- Control frame information ----------------------------------------------- c:0009 p:0011 s:0021 b:0021 l:000888 d:000020 BLOCK ./bug.rb:7 c:0008 p:---- s:0019 b:0019 l:000018 d:000018 FINISH c:0007 p:---- s:0017 b:0017 l:000016 d:000016 CFUNC :times ...
  • 45. (gdb) bt #0 0x00007fff8e611cfb in tiny_free_list_remove_ptr () #1 0x00007fff8e60e76d in szone_free_definite_size () #2 0x00007fff8e608898 in free () #3 0x000000010012f5dc in rb_free_method_entry [inlined] () at vm_method.c:155 #4 0x000000010012f5dc in rb_sweep_method_entry (pvm=0xb592caed) at... #5 0x000000010004a00a in gc_lazy_sweep [inlined] () at gc.c:2107 #6 0x000000010004a00a in rb_newobj () at gc.c:1183 #7 0x000000010000caf4 in ary_alloc [inlined] () at array.c:301 #8 0x000000010000caf4 in ary_new (klass=4303833400, capa=3046355020) at... #9 0x000000010000d165 in rb_ary_new2 [inlined] () at array.c:334 #10 0x000000010000d165 in rb_ary_new4 (n=0, elts=0x7fff5fbfee90) at array.c... #11 0x000000010013288a in vm_yield_with_cfunc (th=0x100303e90, block=... #12 0x000000010013dbb1 in rb_vm_invoke_proc (th=0x100303e90, proc=... #13 0x000000010013bd90 in vm_call_bmethod [inlined] () at vm_insnhelper.c:433 #14 0x000000010013bd90 in vm_call_method (th=0x7fff5fbfef60, cfp=0x7fff5fbfef60, num=8766224, blockptr=0x7fff5fbfef60, flag=140734799802208, id=4298129040, me=0x10038ec90, recv=4303733520) at vm_insnhelper.c:566 ...
  • 46. Call three methods 10,000 times user system total real Pre-delegate ruby(5919,0x7fff732a5180) malloc: *** error for object 0x7fb18f80d750: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug
  • 47. > gdb ./miniruby ... (gdb) break malloc_error_break Function "malloc_error_break" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (malloc_error_break) pending. (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb Reading symbols for shared libraries ++............................ done Breakpoint 1 at 0x7fff8e607558 Pending breakpoint 1 - "malloc_error_break" resolved Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c908 0x00007fff8e611cfb in tiny_free_list_remove_ptr () (gdb)
  • 48. > gdb ./miniruby ... (gdb) break malloc_error_break Function "malloc_error_break" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (malloc_error_break) pending. (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb Reading symbols for shared libraries ++............................ done Breakpoint 1 at 0x7fff8e607558 Pending breakpoint 1 - "malloc_error_break" resolved Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c908 0x00007fff8e611cfb in tiny_free_list_remove_ptr () (gdb)
  • 49. > gdb ./miniruby ... (gdb) break malloc_error_break Function "malloc_error_break" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (malloc_error_break) pending. (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb Reading symbols for shared libraries ++............................ done Breakpoint 1 at 0x7fff8e607558 Pending breakpoint 1 - "malloc_error_break" resolved Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c908 0x00007fff8e611cfb in tiny_free_list_remove_ptr () (gdb)
  • 50. > gdb ./miniruby ... (gdb) break malloc_error_break Function "malloc_error_break" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (malloc_error_break) pending. (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb Reading symbols for shared libraries ++............................ done Breakpoint 1 at 0x7fff8e607558 Pending breakpoint 1 - "malloc_error_break" resolved Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c908 0x00007fff8e611cfb in tiny_free_list_remove_ptr () (gdb)
  • 51. Advanced Weaponry MallocStackLoggingNoCompact • man malloc • Set environment variables to log the stack during allocations • Run in GDB, use malloc_history to view stacks • CFLAGS=”-O0 -g” ./configure
  • 52. (gdb) set environment MallocStackLoggingNoCompact=true (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb zsh(49630) malloc: recording malloc stacks to disk using standard recorder zsh(49630) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly ... Reading symbols for shared libraries ++............................ done miniruby(49630) malloc: recording malloc stacks to disk using standard recorder miniruby(49630) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly miniruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch. 2JF4tB.index miniruby(49630) malloc: stack logs being written into /tmp/stack-logs. 49630.miniruby.lZtwm8.index Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000001000000008 0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
  • 53. (gdb) set environment MallocStackLoggingNoCompact=true (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb zsh(49630) malloc: recording malloc stacks to disk using standard recorder zsh(49630) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly ... Reading symbols for shared libraries ++............................ done miniruby(49630) malloc: recording malloc stacks to disk using standard recorder miniruby(49630) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly miniruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch. 2JF4tB.index miniruby(49630) malloc: stack logs being written into /tmp/stack-logs. 49630.miniruby.lZtwm8.index Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000001000000008 0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
  • 54. (gdb) set environment MallocStackLoggingNoCompact=true (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb zsh(49630) malloc: recording malloc stacks to disk using standard recorder zsh(49630) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly ... Reading symbols for shared libraries ++............................ done miniruby(49630) malloc: recording malloc stacks to disk using standard recorder miniruby(49630) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly miniruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch. 2JF4tB.index miniruby(49630) malloc: stack logs being written into /tmp/stack-logs. 49630.miniruby.lZtwm8.index Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000001000000008 0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
  • 55. (gdb) set environment MallocStackLoggingNoCompact=true (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb zsh(49630) malloc: recording malloc stacks to disk using standard recorder zsh(49630) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly ... Reading symbols for shared libraries ++............................ done miniruby(49630) malloc: recording malloc stacks to disk using standard recorder miniruby(49630) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly miniruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch. 2JF4tB.index miniruby(49630) malloc: stack logs being written into /tmp/stack-logs. 49630.miniruby.lZtwm8.index Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000001000000008 0x00007fff8e611cfb in tiny_free_list_remove_ptr ()
  • 56. (gdb) bt #0 0x00007fff8e611cfb in tiny_free_list_remove_ptr () #1 0x00007fff8e60e76d in szone_free_definite_size () #2 0x00007fff8e608898 in free () #3 0x000000010006f6cc in vm_xfree (objspace=0x10081c400, ptr=0x1004918b0) at gc.c:830 #4 0x000000010006fa76 in ruby_xfree (x=0x1004918b0) at gc.c:894 ...
  • 57. > malloc_history 49630 0x1004918b0 malloc_history Report Version: 2.0 Process: miniruby [49630] ... ALLOC 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main | ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | rb_class_new_instance | rb_obj_call_init | rb_funcall2 | rb_call | rb_call0 | vm_call0 | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | method_proc | rb_iterate | mlambda | rb_funcall | rb_call | rb_call0 | vm_call0 | call_cfunc | proc_lambda | rb_block_lambda | proc_new | rb_vm_make_proc | rb_proc_alloc | ruby_xmalloc | vm_xmalloc | malloc | malloc_zone_malloc ---- FREE 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main | ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_bmethod | rb_vm_invoke_proc | invoke_block_from_c | vm_yield_with_cfunc | bmcall | rb_method_call | rb_vm_call | vm_call0 | rb_threadptr_execute_interrupts | rb_threadptr_execute_interrupts_common | rb_gc_finalize_deferred | finalize_deferred | finalize_list | run_final | proc_free | ruby_xfree | vm_xfree | free
  • 58. > malloc_history 49630 0x1004918b0 malloc_history Report Version: 2.0 Process: miniruby [49630] ... ALLOC 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main | ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | rb_class_new_instance | rb_obj_call_init | rb_funcall2 | rb_call | rb_call0 | vm_call0 | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | method_proc | rb_iterate | mlambda | rb_funcall | rb_call | rb_call0 | vm_call0 | call_cfunc | proc_lambda | rb_block_lambda | proc_new | rb_vm_make_proc | rb_proc_alloc | ruby_xmalloc | vm_xmalloc | malloc | malloc_zone_malloc ---- FREE 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main | ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_bmethod | rb_vm_invoke_proc | invoke_block_from_c | vm_yield_with_cfunc | bmcall | rb_method_call | rb_vm_call | vm_call0 | rb_threadptr_execute_interrupts | rb_threadptr_execute_interrupts_common | rb_gc_finalize_deferred | finalize_deferred | finalize_list | run_final | proc_free | ruby_xfree | vm_xfree | free
  • 59. > malloc_history 49630 0x1004918b0 malloc_history Report Version: 2.0 Process: miniruby [49630] ... ALLOC 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main | ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | rb_class_new_instance | rb_obj_call_init | rb_funcall2 | rb_call | rb_call0 | vm_call0 | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | method_proc | rb_iterate | mlambda | rb_funcall | rb_call | rb_call0 | vm_call0 | call_cfunc | proc_lambda | rb_block_lambda | proc_new | rb_vm_make_proc | rb_proc_alloc | ruby_xmalloc | vm_xmalloc | malloc | malloc_zone_malloc ---- FREE 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main | ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_bmethod | rb_vm_invoke_proc | invoke_block_from_c | vm_yield_with_cfunc | bmcall | rb_method_call | rb_vm_call | vm_call0 | rb_threadptr_execute_interrupts | rb_threadptr_execute_interrupts_common | rb_gc_finalize_deferred | finalize_deferred | finalize_list | run_final | proc_free | ruby_xfree | vm_xfree | free
  • 60. > malloc_history 49630 0x1004918b0 malloc_history Report Version: 2.0 Process: miniruby [49630] ... ALLOC 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main | ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | rb_class_new_instance | rb_obj_call_init | rb_funcall2 | rb_call | rb_call0 | vm_call0 | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | method_proc | rb_iterate | mlambda | rb_funcall | rb_call | rb_call0 | vm_call0 | call_cfunc | proc_lambda | rb_block_lambda | proc_new | rb_vm_make_proc | rb_proc_alloc | ruby_xmalloc | vm_xmalloc | malloc | malloc_zone_malloc ---- FREE 0x1004918b0-0x1004918f7 [size=72]: thread_7fff732a5180 |start | main | ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_bmethod | rb_vm_invoke_proc | invoke_block_from_c | vm_yield_with_cfunc | bmcall | rb_method_call | rb_vm_call | vm_call0 | rb_threadptr_execute_interrupts | rb_threadptr_execute_interrupts_common | rb_gc_finalize_deferred | finalize_deferred | finalize_list | run_final | proc_free | ruby_xfree | vm_xfree | free
  • 61. BFGmalloc libgmalloc.dylib -- (Guard Malloc), an aggressive debugging malloc library
  • 69. (gdb) set environment MallocStackLoggingNoCompact=true (gdb) set environment DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb GuardMalloc[zsh-50147]: recording malloc stacks to disk using standard recorder GuardMalloc[zsh-50147]: stack logging compaction turned off; size of log files on disk can increase rapidly ...
  • 70. (gdb) set environment MallocStackLoggingNoCompact=true (gdb) set environment DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb GuardMalloc[zsh-50147]: recording malloc stacks to disk using standard recorder GuardMalloc[zsh-50147]: stack logging compaction turned off; size of log files on disk can increase rapidly ...
  • 71. (gdb) set environment MallocStackLoggingNoCompact=true (gdb) set environment DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib (gdb) run ./bug.rb Starting program: /Users/jballanc/Source/ruby/miniruby ./bug.rb GuardMalloc[zsh-50147]: recording malloc stacks to disk using standard recorder GuardMalloc[zsh-50147]: stack logging compaction turned off; size of log files on disk can increase rapidly ...
  • 72. Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000107203fe4 0x0000000100208b3c in rb_thread_mark (ptr=0x10085fce0) at vm.c:1733 1733! ! ! if (cfp->me) ((rb_method_entry_t *)cfp->me)->mark = 1; (gdb) p cfp->me $1 = (rb_method_entry_t *) 0x107203fe0
  • 73. Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000107203fe4 0x0000000100208b3c in rb_thread_mark (ptr=0x10085fce0) at vm.c:1733 1733! ! ! if (cfp->me) ((rb_method_entry_t *)cfp->me)->mark = 1; (gdb) p cfp->me $1 = (rb_method_entry_t *) 0x107203fe0
  • 74. > malloc_history 50147 0x107203fe0 malloc_history Report Version: 2.0 Process: miniruby [50147] ... FREE 0x107203fe0-0x107203fff [size=32]: thread_7fff732a5180 |start | main | ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_bmethod | rb_vm_invoke_proc | invoke_block_from_c | vm_yield_with_cfunc | bmcall | rb_method_call | rb_vm_call | vm_call0 | call_cfunc | rb_str_reverse | rb_str_new_with_class | str_new | str_alloc | rb_newobj | gc_lazy_sweep | lazy_sweep | slot_sweep | obj_free | rb_free_m_table | st_foreach | free_method_entry_i | rb_free_method_entry | ruby_xfree | vm_xfree | GMfree | GMmalloc_zone_free
  • 75. > malloc_history 50147 0x107203fe0 malloc_history Report Version: 2.0 Process: miniruby [50147] ... FREE 0x107203fe0-0x107203fff [size=32]: thread_7fff732a5180 |start | main | ruby_run_node | ruby_exec_node | ruby_exec_internal | rb_iseq_eval_main | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_cfunc | call_cfunc | int_dotimes | rb_yield | rb_yield_0 | vm_yield | invoke_block_from_c | vm_exec | vm_exec_core | vm_call_method | vm_call_bmethod | rb_vm_invoke_proc | invoke_block_from_c | vm_yield_with_cfunc | bmcall | rb_method_call | rb_vm_call | vm_call0 | call_cfunc | rb_str_reverse | rb_str_new_with_class | str_new | str_alloc | rb_newobj | gc_lazy_sweep | lazy_sweep | slot_sweep | obj_free | rb_free_m_table | st_foreach | free_method_entry_i | rb_free_method_entry | ruby_xfree | vm_xfree | GMfree | GMmalloc_zone_free
  • 77. Questions? Joshua Ballanco @manhattanmetric https://github.com/jballanc

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n