• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
There and Back Again
 

There and Back Again

on

  • 580 views

The slides for my talk at RubyConf 2012 titled "There and Back Again – or –

The slides for my talk at RubyConf 2012 titled "There and Back Again – or –
How I Set out to Benchmark an Algorithm and Ended Up Fixing Ruby".

Statistics

Views

Total Views
580
Views on SlideShare
546
Embed Views
34

Actions

Likes
0
Downloads
0
Comments
0

4 Embeds 34

http://lanyrd.com 31
https://si0.twimg.com 1
http://www.hanrss.com 1
http://feeds.feedburner.com 1

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

There and Back Again There and Back Again Presentation Transcript

  • There and Back Again – or –How I Set out to Benchmark an Algorithm and Ended Up Fixing Ruby
  • About Me Name: Joshua Ballanco
  • About MeLocation: Ankara, Turkey
  • About MeEmployer:
  • About MeEmployer: Burnside Digital
  • WARNINGThis is an ADVANCED presentation. While you donot need to be an expert on the inner workings ofC Ruby, this talk does presume you are familiarwith concepts such as pointers, memoryallocation, and pages (no, not book pages,memory pages).If you are prone to motion sickness or becomenauseous at the sight of hexadecimal memoryaddresses, this talk may not be for you.
  • Prelude: How can Icontribute to Ruby?
  • Prelude: How can Icontribute 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.rbCall one method user system total realPre-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 realPre-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 realPre-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 debugzsh: 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.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbReading symbols for shared libraries ++............................ doneProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x00000011003971980x00007fff8e611cfb in tiny_free_list_remove_ptr ()(gdb)
  • > gdb ./miniruby...(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbReading symbols for shared libraries ++............................ doneProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x00000011003971980x00007fff8e611cfb in tiny_free_list_remove_ptr ()(gdb)
  • > gdb ./miniruby...(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbReading symbols for shared libraries ++............................ doneProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x00000011003971980x00007fff8e611cfb 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) atvm_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) atvm_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) atvm_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 phaseruby 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:7c:0008 p:---- s:0019 b:0019 l:000018 d:000018 FINISHc: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 phaseruby 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:7c:0008 p:---- s:0019 b:0019 l:000018 d:000018 FINISHc: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) atvm_insnhelper.c:566...
  • Call three methods 10,000 times user system total realPre-delegate ruby(5919,0x7fff732a5180) malloc: *** error for object0x7fb18f80d750: incorrect checksum for freed object - object was probablymodified after being freed.*** set a breakpoint in malloc_error_break to debug
  • > gdb ./miniruby...(gdb) break malloc_error_breakFunction "malloc_error_break" not defined.Make breakpoint pending on future shared library load? (y or [n]) yBreakpoint 1 (malloc_error_break) pending.(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbReading symbols for shared libraries ++............................ doneBreakpoint 1 at 0x7fff8e607558Pending breakpoint 1 - "malloc_error_break" resolvedProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c9080x00007fff8e611cfb in tiny_free_list_remove_ptr ()(gdb)
  • > gdb ./miniruby...(gdb) break malloc_error_breakFunction "malloc_error_break" not defined.Make breakpoint pending on future shared library load? (y or [n]) yBreakpoint 1 (malloc_error_break) pending.(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbReading symbols for shared libraries ++............................ doneBreakpoint 1 at 0x7fff8e607558Pending breakpoint 1 - "malloc_error_break" resolvedProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c9080x00007fff8e611cfb in tiny_free_list_remove_ptr ()(gdb)
  • > gdb ./miniruby...(gdb) break malloc_error_breakFunction "malloc_error_break" not defined.Make breakpoint pending on future shared library load? (y or [n]) yBreakpoint 1 (malloc_error_break) pending.(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbReading symbols for shared libraries ++............................ doneBreakpoint 1 at 0x7fff8e607558Pending breakpoint 1 - "malloc_error_break" resolvedProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c9080x00007fff8e611cfb in tiny_free_list_remove_ptr ()(gdb)
  • > gdb ./miniruby...(gdb) break malloc_error_breakFunction "malloc_error_break" not defined.Make breakpoint pending on future shared library load? (y or [n]) yBreakpoint 1 (malloc_error_break) pending.(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbReading symbols for shared libraries ++............................ doneBreakpoint 1 at 0x7fff8e607558Pending breakpoint 1 - "malloc_error_break" resolvedProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x000000110060c9080x00007fff8e611cfb 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.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbzsh(49630) malloc: recording malloc stacks to disk using standard recorderzsh(49630) malloc: stack logging compaction turned off; size of log files ondisk can increase rapidly...Reading symbols for shared libraries ++............................ doneminiruby(49630) malloc: recording malloc stacks to disk using standard recorderminiruby(49630) malloc: stack logging compaction turned off; size of log fileson disk can increase rapidlyminiruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch.2JF4tB.indexminiruby(49630) malloc: stack logs being written into /tmp/stack-logs.49630.miniruby.lZtwm8.indexProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x00000010000000080x00007fff8e611cfb in tiny_free_list_remove_ptr ()
  • (gdb) set environment MallocStackLoggingNoCompact=true(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbzsh(49630) malloc: recording malloc stacks to disk using standard recorderzsh(49630) malloc: stack logging compaction turned off; size of log files ondisk can increase rapidly...Reading symbols for shared libraries ++............................ doneminiruby(49630) malloc: recording malloc stacks to disk using standard recorderminiruby(49630) malloc: stack logging compaction turned off; size of log fileson disk can increase rapidlyminiruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch.2JF4tB.indexminiruby(49630) malloc: stack logs being written into /tmp/stack-logs.49630.miniruby.lZtwm8.indexProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x00000010000000080x00007fff8e611cfb in tiny_free_list_remove_ptr ()
  • (gdb) set environment MallocStackLoggingNoCompact=true(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbzsh(49630) malloc: recording malloc stacks to disk using standard recorderzsh(49630) malloc: stack logging compaction turned off; size of log files ondisk can increase rapidly...Reading symbols for shared libraries ++............................ doneminiruby(49630) malloc: recording malloc stacks to disk using standard recorderminiruby(49630) malloc: stack logging compaction turned off; size of log fileson disk can increase rapidlyminiruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch.2JF4tB.indexminiruby(49630) malloc: stack logs being written into /tmp/stack-logs.49630.miniruby.lZtwm8.indexProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x00000010000000080x00007fff8e611cfb in tiny_free_list_remove_ptr ()
  • (gdb) set environment MallocStackLoggingNoCompact=true(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbzsh(49630) malloc: recording malloc stacks to disk using standard recorderzsh(49630) malloc: stack logging compaction turned off; size of log files ondisk can increase rapidly...Reading symbols for shared libraries ++............................ doneminiruby(49630) malloc: recording malloc stacks to disk using standard recorderminiruby(49630) malloc: stack logging compaction turned off; size of log fileson disk can increase rapidlyminiruby(49630) malloc: stack logs deleted from /tmp/stack-logs.49630.arch.2JF4tB.indexminiruby(49630) malloc: stack logs being written into /tmp/stack-logs.49630.miniruby.lZtwm8.indexProgram received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x00000010000000080x00007fff8e611cfb 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 0x1004918b0malloc_history Report Version: 2.0Process: 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 0x1004918b0malloc_history Report Version: 2.0Process: 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 0x1004918b0malloc_history Report Version: 2.0Process: 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 0x1004918b0malloc_history Report Version: 2.0Process: 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
  • BFGmalloclibgmalloc.dylib -- (Guard Malloc), an aggressive debugging malloc library
  • BFGmallocmallocgmalloc
  • BFGmallocmallocgmalloc
  • BFGmallocmallocgmalloc
  • BFGmallocmallocgmalloc
  • BFGmallocmallocgmalloc
  • BFGmallocmallocgmalloc
  • BFGmallocmallocgmalloc
  • (gdb) set environment MallocStackLoggingNoCompact=true(gdb) set environment DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbGuardMalloc[zsh-50147]: recording malloc stacks to disk using standard recorderGuardMalloc[zsh-50147]: stack logging compaction turned off; size of log fileson disk can increase rapidly...
  • (gdb) set environment MallocStackLoggingNoCompact=true(gdb) set environment DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbGuardMalloc[zsh-50147]: recording malloc stacks to disk using standard recorderGuardMalloc[zsh-50147]: stack logging compaction turned off; size of log fileson disk can increase rapidly...
  • (gdb) set environment MallocStackLoggingNoCompact=true(gdb) set environment DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib(gdb) run ./bug.rbStarting program: /Users/jballanc/Source/ruby/miniruby ./bug.rbGuardMalloc[zsh-50147]: recording malloc stacks to disk using standard recorderGuardMalloc[zsh-50147]: stack logging compaction turned off; size of log fileson disk can increase rapidly...
  • Program received signal EXC_BAD_ACCESS, Could not access memory.Reason: KERN_INVALID_ADDRESS at address: 0x0000000107203fe40x0000000100208b3c in rb_thread_mark (ptr=0x10085fce0) at vm.c:17331733! ! ! 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: 0x0000000107203fe40x0000000100208b3c in rb_thread_mark (ptr=0x10085fce0) at vm.c:17331733! ! ! if (cfp->me) ((rb_method_entry_t *)cfp->me)->mark = 1;(gdb) p cfp->me$1 = (rb_method_entry_t *) 0x107203fe0
  • > malloc_history 50147 0x107203fe0malloc_history Report Version: 2.0Process: 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 0x107203fe0malloc_history Report Version: 2.0Process: 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 @manhattanmetrichttps://github.com/jballanc