Bug #3781

FIBER_USE_NATIVE が有効だと落ちるスクリプトがある

Added by Makoto Kishimoto about 5 years ago. Updated almost 3 years ago.

Status:Closed
Priority:Normal
Assignee:Narihiro Nakamura
ruby -v:- Backport:

Description

=begin
手元のスクリプト(再現する最小のケースを絞り込むのが無理そうなので、そのまま添付します)が、FIBER_USE_NATIVE が有効な ruby で落ちます。

x86-64 FreeBSD と i686 Linux で落ちかたは違いました。ruby の吐くメッセージとバックトレースを以下それぞれ付けます。

$ ruby19 reduct.rb
reduct.rb:734: [BUG] Segmentation fault
ruby 1.9.3dev (2010-09-01 trunk 29159) [x86_64-freebsd8.0]

-- control frame ----------
c:0012 p:---- s:0036 b:0036 l:000035 d:000035 CFUNC :yield
c:0011 p:0082 s:0032 b:0032 l:000031 d:000031 METHOD reduct.rb:734
c:0010 p:0108 s:0028 b:0028 l:000b38 d:000027 BLOCK reduct.rb:591
c:0009 p:---- s:0021 b:0021 l:000020 d:000020 FINISH
c:0008 p:---- s:0019 b:0019 l:000018 d:000018 CFUNC :instance_eval
c:0007 p:0015 s:0016 b:0016 l:000015 d:000015 METHOD reduct.rb:366
c:0006 p:0016 s:0012 b:0012 l:0002b0 d:000011 BLOCK reduct.rb:716
c:0005 p:---- s:0010 b:0010 l:000009 d:000009 FINISH
c:0004 p:---- s:0008 b:0008 l:000007 d:000007 CFUNC :loop
c:0003 p:0009 s:0005 b:0005 l:0002b0 d:000004 BLOCK reduct.rb:715
c:0002 p:---- s:0003 b:0003 l:000002 d:000002 FINISH
c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------


-- Ruby level backtrace information ----------------------------------------
reduct.rb:715:in block in setup'
reduct.rb:715:in
loop'
reduct.rb:716:in block (2 levels) in setup'
reduct.rb:366:in
do_action'
reduct.rb:366:in instance_eval'
reduct.rb:591:in
block in class:ProgNode'
reduct.rb:734:in call_sub'
reduct.rb:734:in
yield'

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

Abort trap: 6 (core dumped)

$ gdb ruby19 ruby19.core
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...
Core was generated by `ruby19'.
Program terminated with signal 6, Aborted.
Reading symbols from /usr/local/lib/libruby.so.19...done.
Loaded symbols for /usr/local/lib/libruby.so.19
Reading symbols from /lib/libthr.so.3...done.
Loaded symbols for /lib/libthr.so.3
Reading symbols from /usr/lib/librt.so.1...done.
Loaded symbols for /usr/lib/librt.so.1
Reading symbols from /lib/libcrypt.so.5...done.
Loaded symbols for /lib/libcrypt.so.5
Reading symbols from /lib/libm.so.5...done.
Loaded symbols for /lib/libm.so.5
Reading symbols from /lib/libc.so.7...done.
Loaded symbols for /lib/libc.so.7
Reading symbols from /usr/local/lib/ruby/1.9.1/x86_64-freebsd8.0/enc/encdb.so...done.
Loaded symbols for /usr/local/lib/ruby/1.9.1/x86_64-freebsd8.0/enc/encdb.so
Reading symbols from /usr/local/lib/ruby/1.9.1/x86_64-freebsd8.0/enc/trans/transdb.so...done.
Loaded symbols for /usr/local/lib/ruby/1.9.1/x86_64-freebsd8.0/enc/trans/transdb.so
Reading symbols from /usr/local/lib/ruby/1.9.1/x86_64-freebsd8.0/fiber.so...done.
Loaded symbols for /usr/local/lib/ruby/1.9.1/x86_64-freebsd8.0/fiber.so
Reading symbols from /libexec/ld-elf.so.1...done.
Loaded symbols for /libexec/ld-elf.so.1
#0 0x0000000800e011ec in thr_kill () from /lib/libc.so.7
[New Thread 80100ae40 (LWP 100612)]
New Thread 8010041c0 (LWP 100146) bt
#0 0x0000000800e011ec in thr_kill () from /lib/libc.so.7
#1 0x0000000800e9ca7b in abort () from /lib/libc.so.7
#2 0x000000080069cf28 in rb_bug (fmt=Variable "fmt" is not available.
) at ../error.c:253
#3 0x000000080074ee4c in sigsegv (sig=Variable "sig" is not available.
) at ../signal.c:613
#4
#5 0x00000003006b582e in ?? ()
#6 0x0000000801014098 in ?? ()
#7 0x0000000802eebb90 in ?? ()
#8 0x0000000802eebb20 in ?? ()
#9 0x0000000802eebb20 in ?? ()
#10 0x0000000802eebb20 in ?? ()
#11 0x0000000802eebb20 in ?? ()
#12 0x0000000802eebb20 in ?? ()
#13 0x0000000200000003 in ?? ()
#14 0x0000000801014098 in ?? ()
#15 0x00000008018463e0 in ?? ()
#16 0x0000000000000000 in ?? ()
#17 0x0000000000000001 in ?? ()
#18 0x0000000801014000 in ?? ()
#19 0x0000000000000001 in ?? ()
#20 0x0000000801014098 in ?? ()
#21 0x00000008006b5763 in gc_mark_children (objspace=0x802eebae0, ptr=Variable "ptr" is not available.
) at ../gc.c:1546
#22 0x00000008007a4167 in iseq_mark (ptr=0x8013d3800) at ../iseq.c:102
#23 0x00000008006b53cc in gc_mark_children (objspace=0x801014000, ptr=34385191920, lev=2) at ../gc.c:1756
#24 0x00000008006b5763 in gc_mark_children (objspace=0x801014000, ptr=Variable "ptr" is not available.
) at ../gc.c:1546
#25 0x00000008007a4167 in iseq_mark (ptr=0x8013d3900) at ../iseq.c:102
#26 0x00000008006b53cc in gc_mark_children (objspace=0x801014000, ptr=34385192120, lev=2) at ../gc.c:1756
#27 0x00000008006b5763 in gc_mark_children (objspace=0x801014000, ptr=Variable "ptr" is not available.
) at ../gc.c:1546
#28 0x00000008007a4167 in iseq_mark (ptr=0x8013d3a00) at ../iseq.c:102
#29 0x00000008006b53cc in gc_mark_children (objspace=0x801014000, ptr=34385192320, lev=2) at ../gc.c:1756
#30 0x00000008006b5763 in gc_mark_children (objspace=0x801014000, ptr=Variable "ptr" is not available.
) at ../gc.c:1546
#31 0x0000000000000002 in ?? ()
#32 0x0000000801014098 in ?? ()
#33 0x00000008006b4c68 in gc_mark_children (objspace=0x802eec120, ptr=34385287168, lev=0) at ../gc.c:1546
#34 0x00000008006b5763 in gc_mark_children (objspace=0x801014000, ptr=Variable "ptr" is not available.
) at ../gc.c:1546
#35 0x00000008007a415c in iseq_mark (ptr=0x80185d400) at ../iseq.c:103
#36 0x00000008006b53cc in gc_mark_children (objspace=0x801014000, ptr=34385189160, lev=14) at ../gc.c:1756
#37 0x0000000802eec440 in ?? ()
#38 0x00000008006b6750 in mark_key () at ../gc.c:1546
#39 0x00000008006b6830 in mark_entry (key=Variable "key" is not available.
) at ../gc.c:1546
#40 0x00000008007562b0 in st_foreach (table=0x1e8, func=0x1, arg=34385404400) at ../st.c:747
#41 0x00000008006b5619 in gc_mark_children (objspace=0x801014000, ptr=34385383080, lev=13) at ../gc.c:1393
#42 0x0000000802eec470 in ?? ()
#43 0x0000000802eec470 in ?? ()
#44 0x0000000802eec470 in ?? ()
#45 0x0000000802eec470 in ?? ()
#46 0x0000000e01874f98 in ?? ()
#47 0x0000000801014098 in ?? ()
#48 0x0000000000000000 in ?? ()
#49 0x0000000801014000 in ?? ()
#50 0x000000000000000c in ?? ()
#51 0x0000000000000001 in ?? ()
#52 0x0000000000000000 in ?? ()
#53 0x00000008011af3d0 in ?? ()
#54 0x00000008007562b0 in st_foreach (table=0x8006b5619, func=0x802eec470, arg=34408940768) at ../st.c:747
#55 0x00000008006b5619 in gc_mark_children (objspace=0x801014000, ptr=34378218040, lev=12) at ../gc.c:1393
#56 0x00000008006b5619 in gc_mark_children (objspace=0x801014000, ptr=34378218360, lev=11) at ../gc.c:1393
#57 0x00000008006b6830 in mark_entry (key=Variable "key" is not available.
) at ../gc.c:1546
#58 0x00000008007562b0 in st_foreach (table=0x8011af520, func=0x8006b6750 , arg=34408941424) at ../st.c:747
#59 0x00000008006b5619 in gc_mark_children (objspace=0x801014000, ptr=34378217920, lev=10) at ../gc.c:1393
#60 0x00000008006b6830 in mark_entry (key=Variable "key" is not available.
) at ../gc.c:1546
#61 0x00000008007562b0 in st_foreach (table=0x8011af6a0, func=0x8006b6750 , arg=34408941696) at ../st.c:747
#62 0x00000008006b5619 in gc_mark_children (objspace=0x801014000, ptr=34378217760, lev=9) at ../gc.c:1393
#63 0x00000008006b5619 in gc_mark_children (objspace=0x801014098, ptr=34408941680, lev=8) at ../gc.c:1393
#64 0x00000008006b5619 in gc_mark_children (objspace=0x801014000, ptr=34378218200, lev=7) at ../gc.c:1393
#65 0x00000008006b6830 in mark_entry (key=Variable "key" is not available.
) at ../gc.c:1546
#66 0x00000008007562b0 in st_foreach (table=0x8011af460, func=0x8006b6750 , arg=34408942352) at ../st.c:747
#67 0x00000008006b5619 in gc_mark_children (objspace=0x801014000, ptr=34378218000, lev=6) at ../gc.c:1393
#68 0x00000008006b6830 in mark_entry (key=Variable "key" is not available.
) at ../gc.c:1546
#69 0x00000008007562b0 in st_foreach (table=0x8011af5e0, func=0x8006b6750 , arg=34408942624) at ../st.c:747
#70 0x00000008006b5619 in gc_mark_children (objspace=0x801014000, ptr=34378217840, lev=5) at ../gc.c:1393
#71 0x0000000802eecc50 in ?? ()
#72 0x0000000802eecc50 in ?? ()
#73 0x0000000802eecc50 in ?? ()
#74 0x0000000802eecc50 in ?? ()
#75 0x00000008007562b0 in st_foreach (table=0x8006b5619, func=0x802eecc50, arg=34408942784) at ../st.c:747
#76 0x00000008006b3765 in rb_mark_tbl (tbl=0x80138a800) at ../gc.c:1393
#77 0x0000000802eeccd0 in ?? ()
#78 0x0000000802eeccd0 in ?? ()
#79 0x0000000802eeccd0 in ?? ()
#80 0x0000000802eeccd0 in ?? ()
#81 0x00000003006b4852 in ?? ()
#82 0x0000000801014098 in ?? ()
#83 0x0000000802eecd80 in ?? ()
#84 0x0000000802eecd10 in ?? ()
#85 0x0000000802eecd10 in ?? ()
#86 0x0000000802eecd10 in ?? ()
#87 0x0000000802eecd10 in ?? ()
#88 0x0000000802eecd10 in ?? ()
#89 0x00000003007a9a5e in ?? ()
#90 0x0000000801014098 in ?? ()
#91 0x0000000000000000 in ?? ()
#92 0x000000080118fa60 in ?? ()
#93 0x0000000000000003 in ?? ()
#94 0x0000000801014000 in ?? ()
#95 0x0000000000000001 in ?? ()
#96 0x0000000802eecd90 in ?? ()
#97 0x00000008006b582e in gc_mark_children (objspace=0x801014000, ptr=Variable "ptr" is not available.
) at ../gc.c:1546
#98 0xcccccccccccccccd in ?? ()
#99 0x0000000802eece60 in ?? ()
#100 0x00000008006b600d in rb_gc_mark_locations (start=0x802eecdf0, end=Variable "end" is not available.
) at ../gc.c:1546
#101 0x00000008007a7ee5 in env_mark (ptr=0x80204f200) at ../vm.c:204
#102 0x00000008006b53cc in gc_mark_children (objspace=0x801014000, ptr=34377932360, lev=0) at ../gc.c:1756
#103 0x00000008006b6e1d in gc_marks (objspace=0x801014000) at ../gc.c:1309
#104 0x00000008006b7a2f in rb_newobj () at ../gc.c:2033
#105 0x00000008006b7df8 in rb_node_newnode (type=47611112, a0=141733920768, a1=0, a2=1) at ../gc.c:1135
#106 0x00000008018645a8 in ?? ()
#107 0x0000000000000000 in ?? ()
#108 0x00000008018646c0 in ?? ()
#109 0x0000000802d67d98 in ?? ()
#110 0x00000008007bcaed in yield_under (under=Variable "under" is not available.
) at ../vm.c:580
#111 0x00000008007bd46e in specific_eval (argc=0, argv=0x802d60088, klass=6, self=34407317672) at vm_eval.c:1238
#112 0x00000008007bbdc0 in vm_call_method (th=0x80100b600, cfp=0x802d67d98, num=Variable "num" is not available.
) at vm_insnhelper.c:402
#113 0x00000008007b3c21 in vm_exec_core (th=0x80100b600, initial=Variable "initial" is not available.
) at insns.def:1006
#114 0x00000008007bad50 in vm_exec (th=0x80100b600) at ../vm.c:1145
#115 0x00000008007bb654 in invoke_block_from_c (th=0x80100b600, block=0x802d67f20, self=34385315520, argc=0, argv=Variable "argv" is not available.
) at ../vm.c:557
#116 0x00000008007bc738 in loop_i () at ../vm.c:587
#117 0x00000008006a10d0 in rb_rescue2 (b_proc=0x8007bc700 , data1=0, r_proc=0, data2=0) at ../eval.c:646
#118 0x00000008007a915e in rb_f_loop (self=34385315520) at vm_eval.c:817
#119 0x00000008007bbdc0 in vm_call_method (th=0x80100b600, cfp=0x802d67ef8, num=Variable "num" is not available.
) at vm_insnhelper.c:402
#120 0x00000008007b3c21 in vm_exec_core (th=0x80100b600, initial=Variable "initial" is not available.
) at insns.def:1006
#121 0x00000008007bad50 in vm_exec (th=0x80100b600) at ../vm.c:1145
#122 0x00000008007bb654 in invoke_block_from_c (th=0x80100b600, block=0x802ceeba0, self=34385315520, argc=0, argv=Variable "argv" is not available.
) at ../vm.c:557
#123 0x00000008007bba31 in rb_vm_invoke_proc (th=0x80100b600, proc=0x802ceeba0, self=34385315520, argc=0, argv=0x802eeff88,
blockptr=0x0) at ../vm.c:603
#124 0x00000008007c9a68 in rb_fiber_start () at ../cont.c:1110
#125 0x0000000800df2854 in makecontext () from /lib/libc.so.7
#126 0x0000000000000000 in ?? ()
#127 0x0000000000000000 in ?? ()
#128 0x0000000000000000 in ?? ()
#129 0x0000000000000000 in ?? ()

$ ruby19 reduct.rb
reduct.rb:388: [BUG] object allocation during garbage collection phase
ruby 1.9.3dev (2010-08-31 trunk 29154) [i686-linux]

-- control frame ----------
c:0013 p:---- s:0042 b:0042 l:000041 d:000041 CFUNC :(null)
c:0012 p:---- s:0040 b:0040 l:000039 d:000039 CFUNC :new
c:0011 p:0011 s:0037 b:0037 l:000036 d:000036 METHOD reduct.rb:388
c:0010 p:0201 s:0031 b:0031 l:0005bc d:000030 BLOCK reduct.rb:551
c:0009 p:---- s:0021 b:0021 l:000020 d:000020 FINISH
c:0008 p:---- s:0019 b:0019 l:000018 d:000018 CFUNC :instance_eval
c:0007 p:0015 s:0016 b:0016 l:000015 d:000015 METHOD reduct.rb:366
c:0006 p:0016 s:0012 b:0012 l:000d48 d:000011 BLOCK reduct.rb:716
c:0005 p:---- s:0010 b:0010 l:000009 d:000009 FINISH
Segmentation fault (core dumped)

$ gdb ruby19 core.14187
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-23.el5_5.2)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu".
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/...
Reading symbols from /usr/local/bin/ruby19...done.
[New Thread 14188]
Reading symbols from /usr/local/lib/libruby.so.1.9...done.
Loaded symbols for /usr/local/lib/libruby.so.1.9
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /lib/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/libcrypt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libcrypt.so.1
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /usr/local/lib/ruby/1.9.1/i686-linux/enc/encdb.so...done.
Loaded symbols for /usr/local/lib/ruby/1.9.1/i686-linux/enc/encdb.so
Reading symbols from /usr/local/lib/ruby/1.9.1/i686-linux/enc/trans/transdb.so...done.
Loaded symbols for /usr/local/lib/ruby/1.9.1/i686-linux/enc/trans/transdb.so
Reading symbols from /usr/local/lib/ruby/1.9.1/i686-linux/fiber.so...done.
Loaded symbols for /usr/local/lib/ruby/1.9.1/i686-linux/fiber.so
Core was generated by `ruby19 reduct.rb'.
Program terminated with signal 11, Segmentation fault.
#0 0x0022023a in st_lookup (table=0x8357b98, key=2872, value=0x839d764) at ../st.c:342
342 FIND_ENTRY(table, ptr, hash_val, bin_pos);
(gdb) bt
#0 0x0022023a in st_lookup (table=0x8357b98, key=2872, value=0x839d764) at ../st.c:342
#1 0x001bbaae in rb_id2str (id=2872) at parse.y:9796
#2 0x001bbbed in rb_id2name (id=2872) at parse.y:9827
#3 0x0029372a in control_frame_dump (th=0x8325628, cfp=0x8923cc0) at ../vm_dump.c:115
#4 0x00293941 in rb_vmdebug_stack_dump_raw () at ../vm_dump.c:175
#5 rb_vm_bugreport () at ../vm_dump.c:594
#6 0x0015e23d in report_bug (file=, line=,
fmt=0x2a4040 "object allocation during garbage collection phase", args=0x839f924 "") at ../error.c:229
#7 0x0015e2f9 in rb_bug (fmt=0x2a4040 "object allocation during garbage collection phase") at ../error.c:246
#8 0x00179576 in rb_newobj () at ../gc.c:1110
#9 0x002296f7 in str_alloc (capa=120) at ../string.c:378
#10 rb_str_buf_new (capa=120) at ../string.c:742
#11 0x0021d03d in rb_enc_vsprintf (enc=0x8358d98, fmt=0x2a2acd "%s:%d", ap=0x839fa58 "d\301\064\b\204\001")
at ../sprintf.c:1165
#12 0x0021d15e in rb_enc_sprintf (enc=0x8358d98, format=0x2a2acd "%s:%d") at ../sprintf.c:1185
#13 0x001619e1 in setup_exception (th=0x8325628, tag=6, mesg=137682660) at ../eval.c:382
#14 0x00161ca9 in rb_longjmp (mesg=137682660) at ../eval.c:451
#15 rb_exc_raise (mesg=137682660) at ../eval.c:464
#16 0x002948af in ruby_thread_stack_overflow (th=0x8325628) at ../thread.c:1391
#17 0x00219439 in sigsegv (sig=11, info=0x839fb9c, ctx=0x839fc1c) at ../signal.c:602
#18
#19 gc_mark_children (objspace=0x8325890, ptr=138659340, lev=17) at ../gc.c:1557
#20 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138660920, lev=16) at ../gc.c:1546
#21 gc_mark_children (objspace=0x8325890, ptr=138660920, lev=16) at ../gc.c:1765
#22 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138752520, lev=15) at ../gc.c:1546
#23 gc_mark_children (objspace=0x8325890, ptr=138752520, lev=15) at ../gc.c:1765
#24 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138749820, lev=14) at ../gc.c:1546
#25 gc_mark_children (objspace=0x8325890, ptr=138749820, lev=14) at ../gc.c:1765
#26 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138749100, lev=13) at ../gc.c:1546
#27 gc_mark_children (objspace=0x8325890, ptr=138749100, lev=13) at ../gc.c:1765
#28 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138748780, lev=12) at ../gc.c:1546
#29 gc_mark_children (objspace=0x8325890, ptr=138748780, lev=12) at ../gc.c:1765
#30 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138751120, lev=11) at ../gc.c:1546
#31 gc_mark_children (objspace=0x8325890, ptr=138751120, lev=11) at ../gc.c:1765
#32 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138781600, lev=10) at ../gc.c:1546
#33 gc_mark_children (objspace=0x8325890, ptr=138781600, lev=10) at ../gc.c:1765
#34 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138779760, lev=9) at ../gc.c:1546
#35 gc_mark_children (objspace=0x8325890, ptr=138779760, lev=9) at ../gc.c:1765
#36 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138779280, lev=8) at ../gc.c:1546
#37 gc_mark_children (objspace=0x8325890, ptr=138779280, lev=8) at ../gc.c:1765
#38 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138779000, lev=7) at ../gc.c:1546
#39 gc_mark_children (objspace=0x8325890, ptr=138779000, lev=7) at ../gc.c:1765
#40 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138780520, lev=6) at ../gc.c:1546
#41 gc_mark_children (objspace=0x8325890, ptr=138780520, lev=6) at ../gc.c:1765
#42 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138792780, lev=5) at ../gc.c:1546
#43 gc_mark_children (objspace=0x8325890, ptr=138792780, lev=5) at ../gc.c:1765
#44 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138790780, lev=4) at ../gc.c:1546
#45 gc_mark_children (objspace=0x8325890, ptr=138790780, lev=4) at ../gc.c:1765
#46 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138790060, lev=3) at ../gc.c:1546
#47 gc_mark_children (objspace=0x8325890, ptr=138790060, lev=3) at ../gc.c:1765
#48 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138789900, lev=2) at ../gc.c:1546
#49 gc_mark_children (objspace=0x8325890, ptr=138789900, lev=2) at ../gc.c:1765
#50 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138791700, lev=1) at ../gc.c:1546
#51 gc_mark_children (objspace=0x8325890, ptr=138791700, lev=1) at ../gc.c:1765
#52 0x00178221 in gc_mark_locations (start=0x86fdb40, end=0x86fdb5c) at ../gc.c:1546
#53 rb_gc_mark_locations (start=0x86fdb40, end=0x86fdb5c) at ../gc.c:1368
#54 0x00279872 in env_mark (ptr=0x84618d0) at ../vm.c:199
#55 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138791020, lev=1) at ../gc.c:1753
#56 0x0016524a in proc_mark (ptr=0x845f4c0) at ../proc.c:55
#57 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138791000, lev=2) at ../gc.c:1753
#58 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138821120, lev=1) at ../gc.c:1546
#59 gc_mark_children (objspace=0x8325890, ptr=138821120, lev=1) at ../gc.c:1765
#60 0x00178221 in gc_mark_locations (start=0x86dd5fc, end=0x86dd614) at ../gc.c:1546
#61 rb_gc_mark_locations (start=0x86dd5fc, end=0x86dd614) at ../gc.c:1368
#62 0x00279872 in env_mark (ptr=0x86dd5d0) at ../vm.c:199
#63 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138818660, lev=1) at ../gc.c:1753
#64 0x0016524a in proc_mark (ptr=0x86dd618) at ../proc.c:55
#65 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138818640, lev=2) at ../gc.c:1753
#66 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138818720, lev=1) at ../gc.c:1546
#67 gc_mark_children (objspace=0x8325890, ptr=138818720, lev=1) at ../gc.c:1765
#68 0x00178221 in gc_mark_locations (start=0x86dd860, end=0x86dd87c) at ../gc.c:1546
#69 rb_gc_mark_locations (start=0x86dd860, end=0x86dd87c) at ../gc.c:1368
#70 0x00279872 in env_mark (ptr=0x86dd838) at ../vm.c:199
#71 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138818300, lev=1) at ../gc.c:1753
#72 0x0016524a in proc_mark (ptr=0x86dd880) at ../proc.c:55
#73 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138818280, lev=2) at ../gc.c:1753
#74 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138818320, lev=1) at ../gc.c:1546
#75 gc_mark_children (objspace=0x8325890, ptr=138818320, lev=1) at ../gc.c:1765
#76 0x00178221 in gc_mark_locations (start=0x86dd994, end=0x86dd9ac) at ../gc.c:1546
#77 rb_gc_mark_locations (start=0x86dd994, end=0x86dd9ac) at ../gc.c:1368
#78 0x00279872 in env_mark (ptr=0x86dd968) at ../vm.c:199
#79 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138818020, lev=1) at ../gc.c:1753
#80 0x0016524a in proc_mark (ptr=0x86dd9b0) at ../proc.c:55
#81 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138818000, lev=2) at ../gc.c:1753
#82 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138818080, lev=1) at ../gc.c:1546
#83 gc_mark_children (objspace=0x8325890, ptr=138818080, lev=1) at ../gc.c:1765
#84 0x00178221 in gc_mark_locations (start=0x86dda28, end=0x86dda44) at ../gc.c:1546
#85 rb_gc_mark_locations (start=0x86dda28, end=0x86dda44) at ../gc.c:1368
#86 0x00279872 in env_mark (ptr=0x86dda00) at ../vm.c:199
#87 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138817900, lev=1) at ../gc.c:1753
#88 0x0016524a in proc_mark (ptr=0x86dda48) at ../proc.c:55
#89 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138817880, lev=2) at ../gc.c:1753
#90 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138820000, lev=1) at ../gc.c:1546
#91 gc_mark_children (objspace=0x8325890, ptr=138820000, lev=1) at ../gc.c:1765
#92 0x00178221 in gc_mark_locations (start=0x86dd4c0, end=0x86dd4dc) at ../gc.c:1546
#93 rb_gc_mark_locations (start=0x86dd4c0, end=0x86dd4dc) at ../gc.c:1368
#94 0x00279872 in env_mark (ptr=0x86dd498) at ../vm.c:199
#95 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138819200, lev=1) at ../gc.c:1753
#96 0x0016524a in proc_mark (ptr=0x86dd4e0) at ../proc.c:55
#97 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138819100, lev=2) at ../gc.c:1753
#98 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138845500, lev=1) at ../gc.c:1546
#99 gc_mark_children (objspace=0x8325890, ptr=138845500, lev=1) at ../gc.c:1765
#100 0x00178221 in gc_mark_locations (start=0x86bdf7c, end=0x86bdf94) at ../gc.c:1546
#101 rb_gc_mark_locations (start=0x86bdf7c, end=0x86bdf94) at ../gc.c:1368
#102 0x00279872 in env_mark (ptr=0x86bdf50) at ../vm.c:199
#103 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138843200, lev=1) at ../gc.c:1753
#104 0x0016524a in proc_mark (ptr=0x86bdf98) at ../proc.c:55
#105 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138843180, lev=2) at ../gc.c:1753
#106 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138843220, lev=1) at ../gc.c:1546
#107 gc_mark_children (objspace=0x8325890, ptr=138843220, lev=1) at ../gc.c:1765
#108 0x00178221 in gc_mark_locations (start=0x86be1e0, end=0x86be1fc) at ../gc.c:1546
#109 rb_gc_mark_locations (start=0x86be1e0, end=0x86be1fc) at ../gc.c:1368
#110 0x00279872 in env_mark (ptr=0x86be1b8) at ../vm.c:199
#111 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138842840, lev=1) at ../gc.c:1753
#112 0x0016524a in proc_mark (ptr=0x86be200) at ../proc.c:55
#113 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138842820, lev=2) at ../gc.c:1753
#114 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138842860, lev=1) at ../gc.c:1546
#115 gc_mark_children (objspace=0x8325890, ptr=138842860, lev=1) at ../gc.c:1765
#116 0x00178221 in gc_mark_locations (start=0x86be314, end=0x86be32c) at ../gc.c:1546
#117 rb_gc_mark_locations (start=0x86be314, end=0x86be32c) at ../gc.c:1368
#118 0x00279872 in env_mark (ptr=0x86be2e8) at ../vm.c:199
#119 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138842680, lev=1) at ../gc.c:1753
#120 0x0016524a in proc_mark (ptr=0x86be330) at ../proc.c:55
#121 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138842620, lev=2) at ../gc.c:1753
#122 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138842700, lev=1) at ../gc.c:1546
#123 gc_mark_children (objspace=0x8325890, ptr=138842700, lev=1) at ../gc.c:1765
#124 0x00178221 in gc_mark_locations (start=0x86be3a8, end=0x86be3c4) at ../gc.c:1546
#125 rb_gc_mark_locations (start=0x86be3a8, end=0x86be3c4) at ../gc.c:1368
#126 0x00279872 in env_mark (ptr=0x86be380) at ../vm.c:199
#127 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138842520, lev=1) at ../gc.c:1753
#128 0x0016524a in proc_mark (ptr=0x86be3c8) at ../proc.c:55
#129 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138842500, lev=2) at ../gc.c:1753
#130 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138844140, lev=1) at ../gc.c:1546
#131 gc_mark_children (objspace=0x8325890, ptr=138844140, lev=1) at ../gc.c:1765
#132 0x00178221 in gc_mark_locations (start=0x86bde40, end=0x86bde5c) at ../gc.c:1546
#133 rb_gc_mark_locations (start=0x86bde40, end=0x86bde5c) at ../gc.c:1368
#134 0x00279872 in env_mark (ptr=0x86bde18) at ../vm.c:199
#135 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138843460, lev=1) at ../gc.c:1753
#136 0x0016524a in proc_mark (ptr=0x86bde60) at ../proc.c:55
#137 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138843440, lev=2) at ../gc.c:1753
#138 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138856440, lev=1) at ../gc.c:1546
#139 gc_mark_children (objspace=0x8325890, ptr=138856440, lev=1) at ../gc.c:1765
#140 0x00178221 in gc_mark_locations (start=0x84731ec, end=0x8473204) at ../gc.c:1546
#141 rb_gc_mark_locations (start=0x84731ec, end=0x8473204) at ../gc.c:1368
#142 0x00279872 in env_mark (ptr=0x84704b8) at ../vm.c:199
#143 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138854060, lev=1) at ../gc.c:1753
#144 0x0016524a in proc_mark (ptr=0x846eb48) at ../proc.c:55
#145 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138854040, lev=2) at ../gc.c:1753
#146 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138854080, lev=1) at ../gc.c:1546
#147 gc_mark_children (objspace=0x8325890, ptr=138854080, lev=1) at ../gc.c:1765
#148 0x00178221 in gc_mark_locations (start=0x869d808, end=0x869d824) at ../gc.c:1546
#149 rb_gc_mark_locations (start=0x869d808, end=0x869d824) at ../gc.c:1368
#150 0x00279872 in env_mark (ptr=0x8472728) at ../vm.c:199
#151 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138853700, lev=1) at ../gc.c:1753
#152 0x0016524a in proc_mark (ptr=0x846f0d8) at ../proc.c:55
#153 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138853680, lev=2) at ../gc.c:1753
#154 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138853720, lev=1) at ../gc.c:1546
#155 gc_mark_children (objspace=0x8325890, ptr=138853720, lev=1) at ../gc.c:1765
#156 0x00178221 in gc_mark_locations (start=0x869d88c, end=0x869d8a4) at ../gc.c:1546
#157 rb_gc_mark_locations (start=0x869d88c, end=0x869d8a4) at ../gc.c:1368
#158 0x00279872 in env_mark (ptr=0x8472778) at ../vm.c:199
#159 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138853460, lev=1) at ../gc.c:1753
#160 0x0016524a in proc_mark (ptr=0x846f160) at ../proc.c:55
#161 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138853440, lev=2) at ../gc.c:1753
#162 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138853480, lev=1) at ../gc.c:1546
#163 gc_mark_children (objspace=0x8325890, ptr=138853480, lev=1) at ../gc.c:1765
#164 0x00178221 in gc_mark_locations (start=0x869d8c8, end=0x869d8e4) at ../gc.c:1546
#165 rb_gc_mark_locations (start=0x869d8c8, end=0x869d8e4) at ../gc.c:1368
#166 0x00279872 in env_mark (ptr=0x84727a0) at ../vm.c:199
#167 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138853380, lev=1) at ../gc.c:1753
#168 0x0016524a in proc_mark (ptr=0x846f190) at ../proc.c:55
#169 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138853360, lev=2) at ../gc.c:1753
#170 0x00176c5b in gc_mark (objspace=0x8325890, ptr=138855120, lev=1) at ../gc.c:1546
#171 gc_mark_children (objspace=0x8325890, ptr=138855120, lev=1) at ../gc.c:1765
#172 0x00178221 in gc_mark_locations (start=0x8470170, end=0x847018c) at ../gc.c:1546
#173 rb_gc_mark_locations (start=0x8470170, end=0x847018c) at ../gc.c:1368
#174 0x00279872 in env_mark (ptr=0x8470430) at ../vm.c:199
#175 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138854320, lev=1) at ../gc.c:1753
#176 0x0016524a in proc_mark (ptr=0x846eb18) at ../proc.c:55
#177 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=138854300, lev=2) at ../gc.c:1753
#178 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137529340, lev=1) at ../gc.c:1546
#179 gc_mark_children (objspace=0x8325890, ptr=137529340, lev=1) at ../gc.c:1765
#180 0x00178221 in gc_mark_locations (start=0x867d084, end=0x867d09c) at ../gc.c:1546
#181 rb_gc_mark_locations (start=0x867d084, end=0x867d09c) at ../gc.c:1368
#182 0x00279872 in env_mark (ptr=0x867d058) at ../vm.c:199
#183 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137527180, lev=1) at ../gc.c:1753
#184 0x0016524a in proc_mark (ptr=0x867d0a0) at ../proc.c:55
#185 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137527160, lev=2) at ../gc.c:1753
#186 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137527200, lev=1) at ../gc.c:1546
#187 gc_mark_children (objspace=0x8325890, ptr=137527200, lev=1) at ../gc.c:1765
#188 0x00178221 in gc_mark_locations (start=0x867d2e8, end=0x867d304) at ../gc.c:1546
#189 rb_gc_mark_locations (start=0x867d2e8, end=0x867d304) at ../gc.c:1368
#190 0x00279872 in env_mark (ptr=0x867d2c0) at ../vm.c:199
#191 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137526760, lev=1) at ../gc.c:1753
#192 0x0016524a in proc_mark (ptr=0x867d308) at ../proc.c:55
#193 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137526740, lev=2) at ../gc.c:1753
#194 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137526800, lev=1) at ../gc.c:1546
#195 gc_mark_children (objspace=0x8325890, ptr=137526800, lev=1) at ../gc.c:1765
#196 0x00178221 in gc_mark_locations (start=0x867d41c, end=0x867d434) at ../gc.c:1546
#197 rb_gc_mark_locations (start=0x867d41c, end=0x867d434) at ../gc.c:1368
#198 0x00279872 in env_mark (ptr=0x867d3f0) at ../vm.c:199
#199 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137526600, lev=1) at ../gc.c:1753
#200 0x0016524a in proc_mark (ptr=0x867d438) at ../proc.c:55
#201 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137526580, lev=2) at ../gc.c:1753
#202 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137526620, lev=1) at ../gc.c:1546
#203 gc_mark_children (objspace=0x8325890, ptr=137526620, lev=1) at ../gc.c:1765
#204 0x00178221 in gc_mark_locations (start=0x867d4b0, end=0x867d4cc) at ../gc.c:1546
#205 rb_gc_mark_locations (start=0x867d4b0, end=0x867d4cc) at ../gc.c:1368
#206 0x00279872 in env_mark (ptr=0x867d488) at ../vm.c:199
#207 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137526520, lev=1) at ../gc.c:1753
#208 0x0016524a in proc_mark (ptr=0x867d4d0) at ../proc.c:55
#209 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137526500, lev=2) at ../gc.c:1753
#210 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137527980, lev=1) at ../gc.c:1546
#211 gc_mark_children (objspace=0x8325890, ptr=137527980, lev=1) at ../gc.c:1765
#212 0x00178221 in gc_mark_locations (start=0x867cf48, end=0x867cf64) at ../gc.c:1546
#213 rb_gc_mark_locations (start=0x867cf48, end=0x867cf64) at ../gc.c:1368
#214 0x00279872 in env_mark (ptr=0x867cf20) at ../vm.c:199
#215 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137527440, lev=1) at ../gc.c:1753
#216 0x0016524a in proc_mark (ptr=0x867cf68) at ../proc.c:55
#217 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137527420, lev=2) at ../gc.c:1753
#218 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137545100, lev=1) at ../gc.c:1546
#219 gc_mark_children (objspace=0x8325890, ptr=137545100, lev=1) at ../gc.c:1765
#220 0x00178221 in gc_mark_locations (start=0x865cb24, end=0x865cb3c) at ../gc.c:1546
#221 rb_gc_mark_locations (start=0x865cb24, end=0x865cb3c) at ../gc.c:1368
#222 0x00279872 in env_mark (ptr=0x865caf8) at ../vm.c:199
#223 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137543260, lev=1) at ../gc.c:1753
#224 0x0016524a in proc_mark (ptr=0x865cb40) at ../proc.c:55
#225 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137543240, lev=2) at ../gc.c:1753
#226 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137543280, lev=1) at ../gc.c:1546
#227 gc_mark_children (objspace=0x8325890, ptr=137543280, lev=1) at ../gc.c:1765
#228 0x00178221 in gc_mark_locations (start=0x865cd88, end=0x865cda4) at ../gc.c:1546
#229 rb_gc_mark_locations (start=0x865cd88, end=0x865cda4) at ../gc.c:1368
#230 0x00279872 in env_mark (ptr=0x865cd60) at ../vm.c:199
#231 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137542120, lev=1) at ../gc.c:1753
#232 0x0016524a in proc_mark (ptr=0x865cda8) at ../proc.c:55
#233 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137542100, lev=2) at ../gc.c:1753
#234 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137542360, lev=1) at ../gc.c:1546
#235 gc_mark_children (objspace=0x8325890, ptr=137542360, lev=1) at ../gc.c:1765
#236 0x00178221 in gc_mark_locations (start=0x865cebc, end=0x865ced4) at ../gc.c:1546
#237 rb_gc_mark_locations (start=0x865cebc, end=0x865ced4) at ../gc.c:1368
#238 0x00279872 in env_mark (ptr=0x865ce90) at ../vm.c:199
#239 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137541440, lev=1) at ../gc.c:1753
#240 0x0016524a in proc_mark (ptr=0x865ced8) at ../proc.c:55
#241 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137541420, lev=2) at ../gc.c:1753
#242 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137541640, lev=1) at ../gc.c:1546
#243 gc_mark_children (objspace=0x8325890, ptr=137541640, lev=1) at ../gc.c:1765
#244 0x00178221 in gc_mark_locations (start=0x865cf50, end=0x865cf6c) at ../gc.c:1546
#245 rb_gc_mark_locations (start=0x865cf50, end=0x865cf6c) at ../gc.c:1368
#246 0x00279872 in env_mark (ptr=0x865cf28) at ../vm.c:199
#247 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137541200, lev=1) at ../gc.c:1753
#248 0x0016524a in proc_mark (ptr=0x865cf70) at ../proc.c:55
#249 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137541180, lev=2) at ../gc.c:1753
#250 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137544120, lev=1) at ../gc.c:1546
#251 gc_mark_children (objspace=0x8325890, ptr=137544120, lev=1) at ../gc.c:1765
#252 0x00178221 in gc_mark_locations (start=0x865c9e8, end=0x865ca04) at ../gc.c:1546
#253 rb_gc_mark_locations (start=0x865c9e8, end=0x865ca04) at ../gc.c:1368
#254 0x00279872 in env_mark (ptr=0x865c9c0) at ../vm.c:199
#255 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137543580, lev=1) at ../gc.c:1753
#256 0x0016524a in proc_mark (ptr=0x865ca08) at ../proc.c:55
#257 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137543560, lev=2) at ../gc.c:1753
#258 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137554620, lev=1) at ../gc.c:1546
#259 gc_mark_children (objspace=0x8325890, ptr=137554620, lev=1) at ../gc.c:1765
#260 0x00178221 in gc_mark_locations (start=0x863b794, end=0x863b7ac) at ../gc.c:1546
#261 rb_gc_mark_locations (start=0x863b794, end=0x863b7ac) at ../gc.c:1368
#262 0x00279872 in env_mark (ptr=0x8471158) at ../vm.c:199
#263 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137552620, lev=1) at ../gc.c:1753
#264 0x0016524a in proc_mark (ptr=0x8470d78) at ../proc.c:55
#265 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137552600, lev=2) at ../gc.c:1753
#266 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137552640, lev=1) at ../gc.c:1546
#267 gc_mark_children (objspace=0x8325890, ptr=137552640, lev=1) at ../gc.c:1765
#268 0x00178221 in gc_mark_locations (start=0x863b8f0, end=0x863b90c) at ../gc.c:1546
#269 rb_gc_mark_locations (start=0x863b8f0, end=0x863b90c) at ../gc.c:1368
#270 0x00279872 in env_mark (ptr=0x84714a8) at ../vm.c:199
#271 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137552180, lev=1) at ../gc.c:1753
#272 0x0016524a in proc_mark (ptr=0x8470eb8) at ../proc.c:55
#273 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137552160, lev=2) at ../gc.c:1753
#274 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137552200, lev=1) at ../gc.c:1546
#275 gc_mark_children (objspace=0x8325890, ptr=137552200, lev=1) at ../gc.c:1765
#276 0x00178221 in gc_mark_locations (start=0x863b9c4, end=0x863b9dc) at ../gc.c:1546
#277 rb_gc_mark_locations (start=0x863b9c4, end=0x863b9dc) at ../gc.c:1368
#278 0x00279872 in env_mark (ptr=0x863b998) at ../vm.c:199
#279 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137552020, lev=1) at ../gc.c:1753
#280 0x0016524a in proc_mark (ptr=0x8470f40) at ../proc.c:55
#281 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137552000, lev=2) at ../gc.c:1753
#282 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137552040, lev=1) at ../gc.c:1546
#283 gc_mark_children (objspace=0x8325890, ptr=137552040, lev=1) at ../gc.c:1765
#284 0x00178221 in gc_mark_locations (start=0x863ba28, end=0x863ba44) at ../gc.c:1546
#285 rb_gc_mark_locations (start=0x863ba28, end=0x863ba44) at ../gc.c:1368
#286 0x00279872 in env_mark (ptr=0x863ba00) at ../vm.c:199
#287 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137551940, lev=1) at ../gc.c:1753
#288 0x0016524a in proc_mark (ptr=0x8470f10) at ../proc.c:55
#289 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137551880, lev=2) at ../gc.c:1753
#290 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137553500, lev=1) at ../gc.c:1546
#291 gc_mark_children (objspace=0x8325890, ptr=137553500, lev=1) at ../gc.c:1765
#292 0x00178221 in gc_mark_locations (start=0x863b6b0, end=0x863b6cc) at ../gc.c:1546
#293 rb_gc_mark_locations (start=0x863b6b0, end=0x863b6cc) at ../gc.c:1368
#294 0x00279872 in env_mark (ptr=0x84710d0) at ../vm.c:199
#295 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137552880, lev=1) at ../gc.c:1753
#296 0x0016524a in proc_mark (ptr=0x8470da8) at ../proc.c:55
#297 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137552860, lev=2) at ../gc.c:1753
#298 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137563940, lev=1) at ../gc.c:1546
#299 gc_mark_children (objspace=0x8325890, ptr=137563940, lev=1) at ../gc.c:1765
#300 0x00178221 in gc_mark_locations (start=0x861a66c, end=0x861a684) at ../gc.c:1546
#301 rb_gc_mark_locations (start=0x861a66c, end=0x861a684) at ../gc.c:1368
#302 0x00279872 in env_mark (ptr=0x861a640) at ../vm.c:199
#303 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137562140, lev=1) at ../gc.c:1753
#304 0x0016524a in proc_mark (ptr=0x861a688) at ../proc.c:55
#305 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137562120, lev=2) at ../gc.c:1753
#306 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137562160, lev=1) at ../gc.c:1546
#307 gc_mark_children (objspace=0x8325890, ptr=137562160, lev=1) at ../gc.c:1765
#308 0x00178221 in gc_mark_locations (start=0x861a8d0, end=0x861a8ec) at ../gc.c:1546
#309 rb_gc_mark_locations (start=0x861a8d0, end=0x861a8ec) at ../gc.c:1368
#310 0x00279872 in env_mark (ptr=0x861a8a8) at ../vm.c:199
#311 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137561780, lev=1) at ../gc.c:1753
#312 0x0016524a in proc_mark (ptr=0x861a8f0) at ../proc.c:55
#313 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137561760, lev=2) at ../gc.c:1753
#314 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137561800, lev=1) at ../gc.c:1546
#315 gc_mark_children (objspace=0x8325890, ptr=137561800, lev=1) at ../gc.c:1765
#316 0x00178221 in gc_mark_locations (start=0x861aa04, end=0x861aa1c) at ../gc.c:1546
#317 rb_gc_mark_locations (start=0x861aa04, end=0x861aa1c) at ../gc.c:1368
#318 0x00279872 in env_mark (ptr=0x861a9d8) at ../vm.c:199
#319 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137561620, lev=1) at ../gc.c:1753
#320 0x0016524a in proc_mark (ptr=0x861aa20) at ../proc.c:55
#321 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137561600, lev=2) at ../gc.c:1753
#322 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137561640, lev=1) at ../gc.c:1546
#323 gc_mark_children (objspace=0x8325890, ptr=137561640, lev=1) at ../gc.c:1765
#324 0x00178221 in gc_mark_locations (start=0x861aa98, end=0x861aab4) at ../gc.c:1546
#325 rb_gc_mark_locations (start=0x861aa98, end=0x861aab4) at ../gc.c:1368
#326 0x00279872 in env_mark (ptr=0x861aa70) at ../vm.c:199
#327 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137561540, lev=1) at ../gc.c:1753
#328 0x0016524a in proc_mark (ptr=0x861aab8) at ../proc.c:55
#329 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137561520, lev=2) at ../gc.c:1753
#330 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137562940, lev=1) at ../gc.c:1546
#331 gc_mark_children (objspace=0x8325890, ptr=137562940, lev=1) at ../gc.c:1765
#332 0x00178221 in gc_mark_locations (start=0x861a530, end=0x861a54c) at ../gc.c:1546
#333 rb_gc_mark_locations (start=0x861a530, end=0x861a54c) at ../gc.c:1368
#334 0x00279872 in env_mark (ptr=0x861a508) at ../vm.c:199
#335 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137562400, lev=1) at ../gc.c:1753
#336 0x0016524a in proc_mark (ptr=0x861a550) at ../proc.c:55
#337 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137562380, lev=2) at ../gc.c:1753
#338 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137573240, lev=1) at ../gc.c:1546
#339 gc_mark_children (objspace=0x8325890, ptr=137573240, lev=1) at ../gc.c:1765
#340 0x00178221 in gc_mark_locations (start=0x85f9844, end=0x85f985c) at ../gc.c:1546
#341 rb_gc_mark_locations (start=0x85f9844, end=0x85f985c) at ../gc.c:1368
#342 0x00279872 in env_mark (ptr=0x85f9818) at ../vm.c:199
#343 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137571280, lev=1) at ../gc.c:1753
#344 0x0016524a in proc_mark (ptr=0x85f9860) at ../proc.c:55
#345 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137571260, lev=2) at ../gc.c:1753
#346 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137571300, lev=1) at ../gc.c:1546
#347 gc_mark_children (objspace=0x8325890, ptr=137571300, lev=1) at ../gc.c:1765
#348 0x00178221 in gc_mark_locations (start=0x85f9aa8, end=0x85f9ac4) at ../gc.c:1546
#349 rb_gc_mark_locations (start=0x85f9aa8, end=0x85f9ac4) at ../gc.c:1368
#350 0x00279872 in env_mark (ptr=0x85f9a80) at ../vm.c:199
#351 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137570920, lev=1) at ../gc.c:1753
#352 0x0016524a in proc_mark (ptr=0x85f9ac8) at ../proc.c:55
#353 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137570900, lev=2) at ../gc.c:1753
#354 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137570940, lev=1) at ../gc.c:1546
#355 gc_mark_children (objspace=0x8325890, ptr=137570940, lev=1) at ../gc.c:1765
#356 0x00178221 in gc_mark_locations (start=0x83e671c, end=0x83e6734) at ../gc.c:1546
#357 rb_gc_mark_locations (start=0x83e671c, end=0x83e6734) at ../gc.c:1368
#358 0x00279872 in env_mark (ptr=0x83e6418) at ../vm.c:199
#359 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137570680, lev=1) at ../gc.c:1753
#360 0x0016524a in proc_mark (ptr=0x83e6758) at ../proc.c:55
#361 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137570660, lev=2) at ../gc.c:1753
#362 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137570700, lev=1) at ../gc.c:1546
#363 gc_mark_children (objspace=0x8325890, ptr=137570700, lev=1) at ../gc.c:1765
#364 0x00178221 in gc_mark_locations (start=0x83e6818, end=0x83e6834) at ../gc.c:1546
#365 rb_gc_mark_locations (start=0x83e6818, end=0x83e6834) at ../gc.c:1368
#366 0x00279872 in env_mark (ptr=0x83e6470) at ../vm.c:199
#367 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137570600, lev=1) at ../gc.c:1753
#368 0x0016524a in proc_mark (ptr=0x83e66a0) at ../proc.c:55
#369 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137570580, lev=2) at ../gc.c:1753
#370 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137572120, lev=1) at ../gc.c:1546
#371 gc_mark_children (objspace=0x8325890, ptr=137572120, lev=1) at ../gc.c:1765
#372 0x00178221 in gc_mark_locations (start=0x85f9708, end=0x85f9724) at ../gc.c:1546
#373 rb_gc_mark_locations (start=0x85f9708, end=0x85f9724) at ../gc.c:1368
#374 0x00279872 in env_mark (ptr=0x85f96e0) at ../vm.c:199
#375 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137571540, lev=1) at ../gc.c:1753
#376 0x0016524a in proc_mark (ptr=0x85f9728) at ../proc.c:55
#377 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137571520, lev=2) at ../gc.c:1753
#378 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137582500, lev=1) at ../gc.c:1546
#379 gc_mark_children (objspace=0x8325890, ptr=137582500, lev=1) at ../gc.c:1765
#380 0x00178221 in gc_mark_locations (start=0x85d80c4, end=0x85d80dc) at ../gc.c:1546
#381 rb_gc_mark_locations (start=0x85d80c4, end=0x85d80dc) at ../gc.c:1368
#382 0x00279872 in env_mark (ptr=0x85d8098) at ../vm.c:199
#383 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137580680, lev=1) at ../gc.c:1753
#384 0x0016524a in proc_mark (ptr=0x85d80e0) at ../proc.c:55
#385 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137580660, lev=2) at ../gc.c:1753
#386 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137580720, lev=1) at ../gc.c:1546
#387 gc_mark_children (objspace=0x8325890, ptr=137580720, lev=1) at ../gc.c:1765
#388 0x00178221 in gc_mark_locations (start=0x85d8328, end=0x85d8344) at ../gc.c:1546
#389 rb_gc_mark_locations (start=0x85d8328, end=0x85d8344) at ../gc.c:1368
#390 0x00279872 in env_mark (ptr=0x85d8300) at ../vm.c:199
#391 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137580260, lev=1) at ../gc.c:1753
#392 0x0016524a in proc_mark (ptr=0x85d8348) at ../proc.c:55
#393 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137580240, lev=2) at ../gc.c:1753
#394 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137580300, lev=1) at ../gc.c:1546
#395 gc_mark_children (objspace=0x8325890, ptr=137580300, lev=1) at ../gc.c:1765
#396 0x00178221 in gc_mark_locations (start=0x85d845c, end=0x85d8474) at ../gc.c:1546
#397 rb_gc_mark_locations (start=0x85d845c, end=0x85d8474) at ../gc.c:1368
#398 0x00279872 in env_mark (ptr=0x85d8430) at ../vm.c:199
#399 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137580100, lev=1) at ../gc.c:1753
#400 0x0016524a in proc_mark (ptr=0x85d8478) at ../proc.c:55
#401 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137580080, lev=2) at ../gc.c:1753
#402 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137580120, lev=1) at ../gc.c:1546
#403 gc_mark_children (objspace=0x8325890, ptr=137580120, lev=1) at ../gc.c:1765
#404 0x00178221 in gc_mark_locations (start=0x85d84f0, end=0x85d850c) at ../gc.c:1546
#405 rb_gc_mark_locations (start=0x85d84f0, end=0x85d850c) at ../gc.c:1368
#406 0x00279872 in env_mark (ptr=0x85d84c8) at ../vm.c:199
#407 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137580020, lev=1) at ../gc.c:1753
#408 0x0016524a in proc_mark (ptr=0x85d8510) at ../proc.c:55
#409 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137580000, lev=2) at ../gc.c:1753
#410 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137581560, lev=1) at ../gc.c:1546
#411 gc_mark_children (objspace=0x8325890, ptr=137581560, lev=1) at ../gc.c:1765
#412 0x00178221 in gc_mark_locations (start=0x85d7f88, end=0x85d7fa4) at ../gc.c:1546
#413 rb_gc_mark_locations (start=0x85d7f88, end=0x85d7fa4) at ../gc.c:1368
#414 0x00279872 in env_mark (ptr=0x85d7f60) at ../vm.c:199
#415 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137581000, lev=1) at ../gc.c:1753
#416 0x0016524a in proc_mark (ptr=0x85d7fa8) at ../proc.c:55
#417 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137580980, lev=2) at ../gc.c:1753
#418 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137591640, lev=1) at ../gc.c:1546
#419 gc_mark_children (objspace=0x8325890, ptr=137591640, lev=1) at ../gc.c:1765
#420 0x00178221 in gc_mark_locations (start=0x85b721c, end=0x85b7234) at ../gc.c:1546
#421 rb_gc_mark_locations (start=0x85b721c, end=0x85b7234) at ../gc.c:1368
#422 0x00279872 in env_mark (ptr=0x85b71f0) at ../vm.c:199
#423 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137589820, lev=1) at ../gc.c:1753
#424 0x0016524a in proc_mark (ptr=0x85b7238) at ../proc.c:55
#425 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137589800, lev=2) at ../gc.c:1753
#426 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137589840, lev=1) at ../gc.c:1546
#427 gc_mark_children (objspace=0x8325890, ptr=137589840, lev=1) at ../gc.c:1765
#428 0x00178221 in gc_mark_locations (start=0x85b7480, end=0x85b749c) at ../gc.c:1546
#429 rb_gc_mark_locations (start=0x85b7480, end=0x85b749c) at ../gc.c:1368
#430 0x00279872 in env_mark (ptr=0x85b7458) at ../vm.c:199
#431 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137589460, lev=1) at ../gc.c:1753
#432 0x0016524a in proc_mark (ptr=0x85b74a0) at ../proc.c:55
#433 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137589420, lev=2) at ../gc.c:1753
#434 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137589480, lev=1) at ../gc.c:1546
#435 gc_mark_children (objspace=0x8325890, ptr=137589480, lev=1) at ../gc.c:1765
#436 0x00178221 in gc_mark_locations (start=0x85b75b4, end=0x85b75cc) at ../gc.c:1546
#437 rb_gc_mark_locations (start=0x85b75b4, end=0x85b75cc) at ../gc.c:1368
#438 0x00279872 in env_mark (ptr=0x85b7588) at ../vm.c:199
#439 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137589260, lev=1) at ../gc.c:1753
#440 0x0016524a in proc_mark (ptr=0x85b75d0) at ../proc.c:55
#441 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137589200, lev=2) at ../gc.c:1753
#442 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137589280, lev=1) at ../gc.c:1546
#443 gc_mark_children (objspace=0x8325890, ptr=137589280, lev=1) at ../gc.c:1765
#444 0x00178221 in gc_mark_locations (start=0x85b7648, end=0x85b7664) at ../gc.c:1546
#445 rb_gc_mark_locations (start=0x85b7648, end=0x85b7664) at ../gc.c:1368
#446 0x00279872 in env_mark (ptr=0x85b7620) at ../vm.c:199
#447 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137589140, lev=1) at ../gc.c:1753
#448 0x0016524a in proc_mark (ptr=0x85b7668) at ../proc.c:55
#449 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137589120, lev=2) at ../gc.c:1753
#450 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137590620, lev=1) at ../gc.c:1546
#451 gc_mark_children (objspace=0x8325890, ptr=137590620, lev=1) at ../gc.c:1765
#452 0x00178221 in gc_mark_locations (start=0x85b70e0, end=0x85b70fc) at ../gc.c:1546
#453 rb_gc_mark_locations (start=0x85b70e0, end=0x85b70fc) at ../gc.c:1368
#454 0x00279872 in env_mark (ptr=0x85b70b8) at ../vm.c:199
#455 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137590080, lev=1) at ../gc.c:1753
#456 0x0016524a in proc_mark (ptr=0x85b7100) at ../proc.c:55
#457 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137590060, lev=2) at ../gc.c:1753
#458 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137600680, lev=1) at ../gc.c:1546
#459 gc_mark_children (objspace=0x8325890, ptr=137600680, lev=1) at ../gc.c:1765
#460 0x00178221 in gc_mark_locations (start=0x8595b4c, end=0x8595b64) at ../gc.c:1546
#461 rb_gc_mark_locations (start=0x8595b4c, end=0x8595b64) at ../gc.c:1368
#462 0x00279872 in env_mark (ptr=0x8595b20) at ../vm.c:199
#463 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137598940, lev=1) at ../gc.c:1753
#464 0x0016524a in proc_mark (ptr=0x8595b68) at ../proc.c:55
#465 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137598920, lev=2) at ../gc.c:1753
#466 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137598960, lev=1) at ../gc.c:1546
#467 gc_mark_children (objspace=0x8325890, ptr=137598960, lev=1) at ../gc.c:1765
#468 0x00178221 in gc_mark_locations (start=0x8595db0, end=0x8595dcc) at ../gc.c:1546
#469 rb_gc_mark_locations (start=0x8595db0, end=0x8595dcc) at ../gc.c:1368
#470 0x00279872 in env_mark (ptr=0x8595d88) at ../vm.c:199
#471 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137598580, lev=1) at ../gc.c:1753
#472 0x0016524a in proc_mark (ptr=0x8595dd0) at ../proc.c:55
#473 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137598560, lev=2) at ../gc.c:1753
#474 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137598600, lev=1) at ../gc.c:1546
#475 gc_mark_children (objspace=0x8325890, ptr=137598600, lev=1) at ../gc.c:1765
#476 0x00178221 in gc_mark_locations (start=0x8595ee4, end=0x8595efc) at ../gc.c:1546
#477 rb_gc_mark_locations (start=0x8595ee4, end=0x8595efc) at ../gc.c:1368
#478 0x00279872 in env_mark (ptr=0x8595eb8) at ../vm.c:199
#479 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137598420, lev=1) at ../gc.c:1753
#480 0x0016524a in proc_mark (ptr=0x8595f00) at ../proc.c:55
#481 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137598400, lev=2) at ../gc.c:1753
#482 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137598440, lev=1) at ../gc.c:1546
#483 gc_mark_children (objspace=0x8325890, ptr=137598440, lev=1) at ../gc.c:1765
#484 0x00178221 in gc_mark_locations (start=0x8595f78, end=0x8595f94) at ../gc.c:1546
#485 rb_gc_mark_locations (start=0x8595f78, end=0x8595f94) at ../gc.c:1368
#486 0x00279872 in env_mark (ptr=0x8595f50) at ../vm.c:199
#487 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137598340, lev=1) at ../gc.c:1753
#488 0x0016524a in proc_mark (ptr=0x8595f98) at ../proc.c:55
#489 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137598320, lev=2) at ../gc.c:1753
#490 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137599720, lev=1) at ../gc.c:1546
#491 gc_mark_children (objspace=0x8325890, ptr=137599720, lev=1) at ../gc.c:1765
#492 0x00178221 in gc_mark_locations (start=0x8595a10, end=0x8595a2c) at ../gc.c:1546
#493 rb_gc_mark_locations (start=0x8595a10, end=0x8595a2c) at ../gc.c:1368
#494 0x00279872 in env_mark (ptr=0x85959e8) at ../vm.c:199
#495 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137599200, lev=1) at ../gc.c:1753
#496 0x0016524a in proc_mark (ptr=0x8595a30) at ../proc.c:55
#497 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137599180, lev=2) at ../gc.c:1753
#498 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137609980, lev=1) at ../gc.c:1546
#499 gc_mark_children (objspace=0x8325890, ptr=137609980, lev=1) at ../gc.c:1765
#500 0x00178221 in gc_mark_locations (start=0x8574aa4, end=0x8574abc) at ../gc.c:1546
#501 rb_gc_mark_locations (start=0x8574aa4, end=0x8574abc) at ../gc.c:1368
#502 0x00279872 in env_mark (ptr=0x8574a78) at ../vm.c:199
#503 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137607980, lev=1) at ../gc.c:1753
#504 0x0016524a in proc_mark (ptr=0x8574ac0) at ../proc.c:55
#505 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137607960, lev=2) at ../gc.c:1753
#506 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137608000, lev=1) at ../gc.c:1546
#507 gc_mark_children (objspace=0x8325890, ptr=137608000, lev=1) at ../gc.c:1765
#508 0x00178221 in gc_mark_locations (start=0x8574d08, end=0x8574d24) at ../gc.c:1546
#509 rb_gc_mark_locations (start=0x8574d08, end=0x8574d24) at ../gc.c:1368
#510 0x00279872 in env_mark (ptr=0x8574ce0) at ../vm.c:199
#511 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137607580, lev=1) at ../gc.c:1753
#512 0x0016524a in proc_mark (ptr=0x8574d28) at ../proc.c:55
#513 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137607560, lev=2) at ../gc.c:1753
#514 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137607600, lev=1) at ../gc.c:1546
#515 gc_mark_children (objspace=0x8325890, ptr=137607600, lev=1) at ../gc.c:1765
#516 0x00178221 in gc_mark_locations (start=0x8574e3c, end=0x8574e54) at ../gc.c:1546
#517 rb_gc_mark_locations (start=0x8574e3c, end=0x8574e54) at ../gc.c:1368
#518 0x00279872 in env_mark (ptr=0x8574e10) at ../vm.c:199
#519 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137607420, lev=1) at ../gc.c:1753
#520 0x0016524a in proc_mark (ptr=0x8574e58) at ../proc.c:55
#521 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137607400, lev=2) at ../gc.c:1753
#522 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137607440, lev=1) at ../gc.c:1546
#523 gc_mark_children (objspace=0x8325890, ptr=137607440, lev=1) at ../gc.c:1765
#524 0x00178221 in gc_mark_locations (start=0x8574ed0, end=0x8574eec) at ../gc.c:1546
#525 rb_gc_mark_locations (start=0x8574ed0, end=0x8574eec) at ../gc.c:1368
#526 0x00279872 in env_mark (ptr=0x8574ea8) at ../vm.c:199
#527 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137607340, lev=1) at ../gc.c:1753
#528 0x0016524a in proc_mark (ptr=0x8574ef0) at ../proc.c:55
#529 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137607320, lev=2) at ../gc.c:1753
#530 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137608880, lev=1) at ../gc.c:1546
#531 gc_mark_children (objspace=0x8325890, ptr=137608880, lev=1) at ../gc.c:1765
#532 0x00178221 in gc_mark_locations (start=0x8574968, end=0x8574984) at ../gc.c:1546
#533 rb_gc_mark_locations (start=0x8574968, end=0x8574984) at ../gc.c:1368
#534 0x00279872 in env_mark (ptr=0x8574940) at ../vm.c:199
#535 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137608240, lev=1) at ../gc.c:1753
#536 0x0016524a in proc_mark (ptr=0x8574988) at ../proc.c:55
#537 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137608220, lev=2) at ../gc.c:1753
#538 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137619760, lev=1) at ../gc.c:1546
#539 gc_mark_children (objspace=0x8325890, ptr=137619760, lev=1) at ../gc.c:1765
#540 0x00178221 in gc_mark_locations (start=0x855355c, end=0x8553574) at ../gc.c:1546
#541 rb_gc_mark_locations (start=0x855355c, end=0x8553574) at ../gc.c:1368
#542 0x00279872 in env_mark (ptr=0x8553530) at ../vm.c:199
#543 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137617740, lev=1) at ../gc.c:1753
#544 0x0016524a in proc_mark (ptr=0x845dad0) at ../proc.c:55
#545 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137617720, lev=2) at ../gc.c:1753
#546 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137617760, lev=1) at ../gc.c:1546
#547 gc_mark_children (objspace=0x8325890, ptr=137617760, lev=1) at ../gc.c:1765
#548 0x00178221 in gc_mark_locations (start=0x8553730, end=0x855374c) at ../gc.c:1546
#549 rb_gc_mark_locations (start=0x8553730, end=0x855374c) at ../gc.c:1368
#550 0x00279872 in env_mark (ptr=0x8553708) at ../vm.c:199
#551 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137617320, lev=1) at ../gc.c:1753
#552 0x0016524a in proc_mark (ptr=0x845dd30) at ../proc.c:55
#553 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137617300, lev=2) at ../gc.c:1753
#554 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137617340, lev=1) at ../gc.c:1546
#555 gc_mark_children (objspace=0x8325890, ptr=137617340, lev=1) at ../gc.c:1765
#556 0x00178221 in gc_mark_locations (start=0x8553804, end=0x855381c) at ../gc.c:1546
#557 rb_gc_mark_locations (start=0x8553804, end=0x855381c) at ../gc.c:1368
#558 0x00279872 in env_mark (ptr=0x85537d8) at ../vm.c:199
#559 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137617140, lev=1) at ../gc.c:1753
#560 0x0016524a in proc_mark (ptr=0x845ddb8) at ../proc.c:55
#561 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137617120, lev=2) at ../gc.c:1753
#562 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137617160, lev=1) at ../gc.c:1546
#563 gc_mark_children (objspace=0x8325890, ptr=137617160, lev=1) at ../gc.c:1765
#564 0x00178221 in gc_mark_locations (start=0x8553868, end=0x8553884) at ../gc.c:1546
#565 rb_gc_mark_locations (start=0x8553868, end=0x8553884) at ../gc.c:1368
#566 0x00279872 in env_mark (ptr=0x8553840) at ../vm.c:199
#567 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137617060, lev=1) at ../gc.c:1753
#568 0x0016524a in proc_mark (ptr=0x845de70) at ../proc.c:55
#569 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137617040, lev=2) at ../gc.c:1753
#570 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137618580, lev=1) at ../gc.c:1546
#571 gc_mark_children (objspace=0x8325890, ptr=137618580, lev=1) at ../gc.c:1765
#572 0x00178221 in gc_mark_locations (start=0x8553450, end=0x855346c) at ../gc.c:1546
#573 rb_gc_mark_locations (start=0x8553450, end=0x855346c) at ../gc.c:1368
#574 0x00279872 in env_mark (ptr=0x8553428) at ../vm.c:199
#575 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137618000, lev=1) at ../gc.c:1753
#576 0x0016524a in proc_mark (ptr=0x845da40) at ../proc.c:55
#577 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137617980, lev=2) at ../gc.c:1753
#578 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137629260, lev=1) at ../gc.c:1546
#579 gc_mark_children (objspace=0x8325890, ptr=137629260, lev=1) at ../gc.c:1765
#580 0x00178221 in gc_mark_locations (start=0x8532514, end=0x853252c) at ../gc.c:1546
#581 rb_gc_mark_locations (start=0x8532514, end=0x853252c) at ../gc.c:1368
#582 0x00279872 in env_mark (ptr=0x85324e8) at ../vm.c:199
#583 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137627480, lev=1) at ../gc.c:1753
#584 0x0016524a in proc_mark (ptr=0x8532530) at ../proc.c:55
#585 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137627440, lev=2) at ../gc.c:1753
#586 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137627500, lev=1) at ../gc.c:1546
#587 gc_mark_children (objspace=0x8325890, ptr=137627500, lev=1) at ../gc.c:1765
#588 0x00178221 in gc_mark_locations (start=0x8532778, end=0x8532794) at ../gc.c:1546
#589 rb_gc_mark_locations (start=0x8532778, end=0x8532794) at ../gc.c:1368
#590 0x00279872 in env_mark (ptr=0x8532750) at ../vm.c:199
#591 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137626940, lev=1) at ../gc.c:1753
#592 0x0016524a in proc_mark (ptr=0x8532798) at ../proc.c:55
#593 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137626920, lev=2) at ../gc.c:1753
#594 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137626960, lev=1) at ../gc.c:1546
#595 gc_mark_children (objspace=0x8325890, ptr=137626960, lev=1) at ../gc.c:1765
#596 0x00178221 in gc_mark_locations (start=0x85328ac, end=0x85328c4) at ../gc.c:1546
#597 rb_gc_mark_locations (start=0x85328ac, end=0x85328c4) at ../gc.c:1368
#598 0x00279872 in env_mark (ptr=0x8532880) at ../vm.c:199
#599 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137626780, lev=1) at ../gc.c:1753
#600 0x0016524a in proc_mark (ptr=0x85328c8) at ../proc.c:55
#601 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137626760, lev=2) at ../gc.c:1753
#602 0x00176c5b in gc_mark (objspace=0x8325890, ptr=137626800, lev=1) at ../gc.c:1546
#603 gc_mark_children (objspace=0x8325890, ptr=137626800, lev=1) at ../gc.c:1765
#604 0x00178221 in gc_mark_locations (start=0x8532940, end=0x853295c) at ../gc.c:1546
#605 rb_gc_mark_locations (start=0x8532940, end=0x853295c) at ../gc.c:1368
#606 0x00279872 in env_mark (ptr=0x8532918) at ../vm.c:199
#607 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137626700, lev=1) at ../gc.c:1753
#608 0x0016524a in proc_mark (ptr=0x8532960) at ../proc.c:55
#609 0x001770e0 in gc_mark_children (objspace=0x8325890, ptr=137626680, lev=2) at ../gc.c:1753
#610 0x00176c5b in gc_mark (objspace=0x8325890,

reduct.rb Magnifier (15.9 KB) Makoto Kishimoto, 09/02/2010 08:38 AM

reduct.rb Magnifier - 2011/Aug/24 (15.9 KB) Makoto Kishimoto, 08/24/2011 09:36 AM


Related issues

Related to Ruby trunk - Bug #4983: Fiberのガードページの設定が間違ってる Closed 07/06/2011
Related to Ruby trunk - Bug #1813: Threading seg fault (1.9.1-p129 Linux/Mac) Closed 07/24/2009

Associated revisions

Revision 32438
Added by nari about 4 years ago

  • gc.c: change water_mark value value that may call
    gc_mark(lev <= GC_LEVEL_MAX) in gc_mark().
    In ruby_stack_check(), water_mark is a value that may call some
    C function. Fixes Bug #3781

  • configure.in: define GC_MARK_STACKFRAME_WORD that approximate
    size of gc_mark() and gc_mark_children() stackframes.

Revision 32438
Added by nari about 4 years ago

  • gc.c: change water_mark value value that may call
    gc_mark(lev <= GC_LEVEL_MAX) in gc_mark().
    In ruby_stack_check(), water_mark is a value that may call some
    C function. Fixes Bug #3781

  • configure.in: define GC_MARK_STACKFRAME_WORD that approximate
    size of gc_mark() and gc_mark_children() stackframes.

History

#1 Updated by Makoto Kishimoto about 5 years ago

=begin
きしもとです

(2) FIBER_USE_NATIVE を 0 にしとく

とあるんですが #ifdef FIBER_USE_NATIVE としてるので、#undef FIBER_USE_NATIVE
しないと無効になりませんでした。

=end

#2 Updated by Makoto Kishimoto about 5 years ago

=begin
きしもとです

On Fri, 3 Sep 2010 15:30:39 +0900
Satoshi Shiba shiba@rvm.jp wrote:

芝と申します。

Makoto Kishimoto wrote:

Bug #3781: FIBER_USE_NATIVE が有効だと落ちるスクリプトがある
http://redmine.ruby-lang.org/issues/show/3781

起票者: Makoto Kishimoto
ステータス: Open, 優先度: Normal
カテゴリ: core, Target version: 1.9.3
ruby -v: ruby 1.9.3dev (2010-09-01 trunk 29159) [x86_64-freebsd8.0]

手元のスクリプト(再現る最小のケースを絞り込むのが無理そうなので、そのまま添付します)が、FIBER_USE_NATIVE が有効な ruby で落ちます。

x86-64 FreeBSD と i686 Linux で落ちかたは違いました。ruby の吐くメッセージとバックトレースを以下そぞれ付けます。

落ちる原因を調べたので、ご報告いたします。

i686 Linux 環境で調べたところ、gc 中に C のスタックオーバーフローを起こ
すことが原因のようです。

[BUG] object allocation during garbage collection phase
というメッセージは、gc 中に C のスタックオーバーフローが発生し、それに対
するバックトレースを生成しようとして吐いているみたいです。

きしもとさんからのご報告にあったバックトレースを見れば分かるように、gc
時に C のスタックが結構な勢いで伸びているため(これぐらい普通なのか
な)、C のスタック領域を64KBしか確保しない現在の Fiber の実装だと C のス
タック領域が GC 中に足りなくなってしまっているようです。

下のパッチのように Fiber に対して割り当てる C のスタックサイズを増やせ
ば、(根本的な解決には全くなっていませんが)きしもとさんからのご報告に添
付されていた reduct.rb で落ちることはなくなりました。

GC 中にスタックオーバーフローが発生しそうなときって今はどう対応してるん
でしょう? gc.c 内の stack_check() の返り値が 1 になっても特に例外を吐く
ようなことはしていないみたいなんですが。

差分を試したところ、i686 Linux では落ちなくなりました。
どうもえらくGCと相性の悪い構造を内部で作ってしまうらしく、スクリプト内の
tarai 100 50 0 を tarai 1000 500 0 とするとやはり落ちます。

x86-64 FreeBSD では、差分を当ててみてもほぼ同じように落ちました。

=end

#3 Updated by Makoto Kishimoto about 5 years ago

=begin

x86-64 FreeBSD では、差分を当ててみてもほぼ同じように落ちました。

スタックサイズを 16 倍にしたところ、FreeBSD でも落ちなくなりました。

=end

#4 Updated by Shyouhei Urabe almost 5 years ago

  • Status changed from Open to Assigned
  • Assignee set to Koichi Sasada

=begin

=end

#5 Updated by Motohiro KOSAKI about 4 years ago

スタックを食いつぶしてるのはGC処理だと最初に書いてあるのに、nariさんの見解が出てないのはどうしてでしょう?
スタックサイズを大きくすれば当然最大ファイバー数が減るので、想定スタック消費量の見解がないとスタックサイズ変更の決定なんて出来ない気がするのですが。
もしくは32bitでは常に FIBER_USE_NATIVEがfalseになるようにして逃げるという手もあると思います。
どちらにしろ決める問題だと思うので意見を出して欲しいです > 関係者各位

#6 Updated by Narihiro Nakamura about 4 years ago

nariです。

もうしわけないんですが、Fiberはあんまりわかってないので、GCのスタックオー
バフロー対策についてお答えします。

現在のマークは、基本的にはオブジェクト、子オブジェクト、孫オブジェクト
と、gc_mark()を再帰的に呼び出すという実装になっています。
オブジェクトがもしすごく深い木を持っていた場合にはマシンスタックが溢れ
るので、GCが「あ、スタックが溢れそう」と判断するとそれ以上はスタックを
使わない方法でマークを行おうとします。

「スタックが溢れそう」というのをチェックする処理はgc_mark()の以下のコー
ドです。

if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
   ...
}

GC_LEVEL_MAXは250に設定されているので、このエラーとは無関係です
(lev=17でスタックオーバフローしているようですので)。

なので、stack_check()が本当は真にならないといけないはずですが、そうはなっ
ていないのだと思われます。

きしもとさんからのご報告にあったバックトレースを見れば分かるように、gc
時に C のスタックが結構な勢いで伸びているため(これぐらい普通なのか
な)、C のスタック領域を64KBしか確保しない現在の Fiber の実装だと C のス
タック領域が GC 中に足りなくなってしまっているようです。

もし、64KBのスタック領域でGCするのであれば、その情報を
th->machine_stack_maxsize に設定しなければならないはずで、
その辺りがうまくいってないのではないでしょうか。

#7 Updated by Yusuke Endoh about 4 years ago

  • ruby -v changed from ruby 1.9.3dev (2010-09-01 trunk 29159) [x86_64-freebsd8.0] to -

遠藤です。

2011年6月30日21:11 Narihiro Nakamura authorNari@gmail.com:

もし、64KBのスタック領域でGCするのであれば、その情報を
th->machine_stack_maxsize に設定しなければならないはずで、
その辺りがうまくいってないのではないでしょうか。

私もその辺りを疑って puts デバッグしてみたんですが、stack_check() は
ちゃんと真になってるみたいです。ふしぎ。

diff --git a/gc.c b/gc.c
index d5b8dfd..577131c 100644
--- a/gc.c
+++ b/gc.c
@@ -1619,6 +1619,7 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {
*mark_stack_ptr = ptr;
mark_stack_ptr++;
+ puts("push");
}
else {
mark_stack_overflow = 1;

$ ./ruby reduct.rb
push
push
push

snip

push
push
push
reduct.rb:114: [BUG] object allocation during garbage collection phase
ruby 1.9.3dev (2011-06-30 trunk 32300) [i686-linux]

--
Yusuke Endoh mame@tsg.ne.jp

#8 Updated by Narihiro Nakamura about 4 years ago

  • Assignee changed from Koichi Sasada to Narihiro Nakamura

nariです。

原因が大体わかったので、あとで再現コードとパッチ作ります。
とりあえず担当者を変えておきます。

#9 Updated by Narihiro Nakamura about 4 years ago

nariです。

redmineだとruby-coreにメールされてしまうので、ruby-devにふります。
スタックオーバフローの原因は以下の2点です。

(1)マーク時に深い関数呼び出ししてしまうデータ構造が作り出される。
(2)gc.cのstack_check()がうまく働かない。

(1)についてはバックトレースを見るとよくわかるのですが、

#1 0x00041e46c in gc_mark_children (objspace=.., ptr=12478400,
lev=19) at gc.c:1797
#2 0x00041e199 in gc_mark (objspace=.., ptr=12478400, lev=18) at gc.c:1630
#3 0x00041e73f in gc_mark_children (objspace=.., ptr=12483880,
lev=18) at gc.c:1850
#4 0x00041e199 in gc_mark (objspace=.., ptr=12483880, lev=17) at gc.c:1630
#5 0x00041e73f in gc_mark_children (objspace=.., ptr=12374280,
lev=17) at gc.c:1850
#6 0x00041e199 in gc_mark (objspace=.., ptr=12374280, lev=16) at gc.c:1630
....
#49 0x00041e73f in gc_mark_children (objspace=.., ptr=12320800,
lev=1) at gc.c:1850
#50 0x00041e199 in gc_mark (objspace=.., ptr=12320800, lev=0) at gc.c:1630
#51 0x00041da86 in mark_locations_array (objspace=.., x=0xe24278,
n=5) at gc.c:1401
#52 0x00041daf3 in gc_mark_locations (objspace=.., start=0xe24270,
end=0xe242a8) at gc.c:1414
#53 0x00041db29 in rb_gc_mark_locations (start=0xe24270,
end=0xe242a8) at gc.c:1420
#54 0x000525fc5 in env_mark (ptr=0xe24220) at vm.c:238
#55 0x00041e6aa in gc_mark_children (objspace=.., ptr=12320440,
lev=1) at gc.c:1838
#56 0x00041e199 in gc_mark (objspace=.., ptr=12320440, lev=0) at gc.c:1630
#57 0x00041e1da in rb_gc_mark (ptr=12320440) at gc.c:1636
#58 0x0004182d1 in proc_mark (ptr=0xe242b0) at proc.c:53
....
#66 0x000525fc5 in env_mark (ptr=0xe24340) at vm.c:238
...
#70 0x0004182d1 in proc_mark (ptr=0xe243d0) at proc.c:53
...
#78 0x000525fc5 in env_mark (ptr=0xe238e0) at vm.c:238
...
#82 0x0004182d1 in proc_mark (ptr=0xe23970) at proc.c:53
...
#90 0x000525fc5 in env_mark (ptr=0xde1580) at vm.c:238
...
#94 0x0004182d1 in proc_mark (ptr=0xde1610) at proc.c:53
...
#514 0x00041863e in binding_mark (ptr=0x95bb30) at proc.c:256

binding_markからはじまって、proc_mark,env_mark,proc_mark.... と続いてし
まうデータ構造がreduct.rbで作り出されています。
このようなデータ構造を作る最小の再現コードを書こうと思ったのですが意外
と難しく断念しました…。

上記のようなデータ構造を作ってしまうのはしょうがなさそうなので、(1)は問
題ではないと思っています。

続いて(2)です。

gc.cのstack_check()の役割としては
「lev(gc_mark()に渡される引数)がGC_LEVEL_MAX(250)の範囲でgc_mark()
を呼び出せるほどの余りがマシンスタックにあるかチェックする」
のように読めます。

static int
stack_check(void)
{
...
SET_STACK_END;
ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;

ただ、GC_WATER_MARKが512しかないので、そのチェックがうまくいってません。
GC_WATER_MARK = (gc_mark()フレームサイズ + gc_mark_children()フレームサイズ) * GC_LEVEL_MAX
となるべきだと思います。

私の環境(Linux 2.6.39-0-generic x86_64, gcc 4.5.2)ではgc_mark()と
gc_mark_children()のフレームが28ワードだったので、とりあえず以下のよう
に修正したいのですが、どうでしょうか?

この場合、GC_WATER_MARKは7000(64bit環境だと56KB)になります。
本当はgc_mark()の際に毎回stack_check()するのがいいと思うのですが、
そうするとGCの性能が落ちてしまうので、大体で決めてしまうしかないのか
なと思ってます。

diff --git a/gc.c b/gc.c
index d5b8dfd..df3fef9 100644
--- a/gc.c
+++ b/gc.c
@@ -1277,7 +1277,8 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
}
#endif

-#define GC_WATER_MARK 512
+#define GC_LEVEL_MAX 250
+#define GC_WATER_MARK (GC_LEVEL_MAX * 28)

size_t
ruby_stack_length(VALUE **p)
@@ -1600,8 +1601,6 @@ rb_gc_mark_maybe(VALUE obj)
}
}

-#define GC_LEVEL_MAX 250
-
static void
gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
{

#10 Updated by Narihiro Nakamura about 4 years ago

nariです。

redmineだとruby-coreにメールされてしまうので、ruby-devにふります。
スタックオーバフローの原因は以下の2点です。

(1)マーク時に深い関数呼び出ししてしまうデータ構造が作り出される。
(2)gc.cのstack_check()がうまく働かない。

(1)についてはバックトレースを見るとよくわかるのですが、

#1 0x00041e46c in gc_mark_children (objspace=.., ptr=12478400,
lev=19) at gc.c:1797
#2 0x00041e199 in gc_mark (objspace=.., ptr=12478400, lev=18) at gc.c:1630
#3 0x00041e73f in gc_mark_children (objspace=.., ptr=12483880,
lev=18) at gc.c:1850
#4 0x00041e199 in gc_mark (objspace=.., ptr=12483880, lev=17) at gc.c:1630
#5 0x00041e73f in gc_mark_children (objspace=.., ptr=12374280,
lev=17) at gc.c:1850
#6 0x00041e199 in gc_mark (objspace=.., ptr=12374280, lev=16) at gc.c:1630
....
#49 0x00041e73f in gc_mark_children (objspace=.., ptr=12320800,
lev=1) at gc.c:1850
#50 0x00041e199 in gc_mark (objspace=.., ptr=12320800, lev=0) at gc.c:1630
#51 0x00041da86 in mark_locations_array (objspace=.., x=0xe24278,
n=5) at gc.c:1401
#52 0x00041daf3 in gc_mark_locations (objspace=.., start=0xe24270,
end=0xe242a8) at gc.c:1414
#53 0x00041db29 in rb_gc_mark_locations (start=0xe24270,
end=0xe242a8) at gc.c:1420
#54 0x000525fc5 in env_mark (ptr=0xe24220) at vm.c:238
#55 0x00041e6aa in gc_mark_children (objspace=.., ptr=12320440,
lev=1) at gc.c:1838
#56 0x00041e199 in gc_mark (objspace=.., ptr=12320440, lev=0) at gc.c:1630
#57 0x00041e1da in rb_gc_mark (ptr=12320440) at gc.c:1636
#58 0x0004182d1 in proc_mark (ptr=0xe242b0) at proc.c:53
....
#66 0x000525fc5 in env_mark (ptr=0xe24340) at vm.c:238
...
#70 0x0004182d1 in proc_mark (ptr=0xe243d0) at proc.c:53
...
#78 0x000525fc5 in env_mark (ptr=0xe238e0) at vm.c:238
...
#82 0x0004182d1 in proc_mark (ptr=0xe23970) at proc.c:53
...
#90 0x000525fc5 in env_mark (ptr=0xde1580) at vm.c:238
...
#94 0x0004182d1 in proc_mark (ptr=0xde1610) at proc.c:53
...
#514 0x00041863e in binding_mark (ptr=0x95bb30) at proc.c:256

binding_markからはじまって、proc_mark,env_mark,proc_mark.... と続いてし
まうデータ構造がreduct.rbで作り出されています。
このようなデータ構造を作る最小の再現コードを書こうと思ったのですが意外
と難しく断念しました…。

上記のようなデータ構造を作ってしまうのはしょうがなさそうなので、(1)は問
題ではないと思っています。

続いて(2)です。

gc.cのstack_check()の役割としては
「lev(gc_mark()に渡される引数)がGC_LEVEL_MAX(250)の範囲でgc_mark()
を呼び出せるほどの余りがマシンスタックにあるかチェックする」
のように読めます。

static int
stack_check(void)
{
...
SET_STACK_END;
ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;

ただ、GC_WATER_MARKが512しかないので、そのチェックがうまくいってません。
GC_WATER_MARK = (gc_mark()フレームサイズ + gc_mark_children()フレームサイズ) * GC_LEVEL_MAX
となるべきだと思います。

私の環境(Linux 2.6.39-0-generic x86_64, gcc 4.5.2)ではgc_mark()と
gc_mark_children()のフレームが28ワードだったので、とりあえず以下のよう
に修正したいのですが、どうでしょうか?

この場合、GC_WATER_MARKは7000(64bit環境だと56KB)になります。
本当はgc_mark()の際に毎回stack_check()するのがいいと思うのですが、
そうするとGCの性能が落ちてしまうので、大体で決めてしまうしかないのか
なと思ってます。

diff --git a/gc.c b/gc.c
index d5b8dfd..df3fef9 100644
--- a/gc.c
+++ b/gc.c
@@ -1277,7 +1277,8 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
}
#endif

-#define GC_WATER_MARK 512
+#define GC_LEVEL_MAX 250
+#define GC_WATER_MARK (GC_LEVEL_MAX * 28)

size_t
ruby_stack_length(VALUE **p)
@@ -1600,8 +1601,6 @@ rb_gc_mark_maybe(VALUE obj)
}
}

-#define GC_LEVEL_MAX 250
-
static void
gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
{

#11 Updated by Motohiro KOSAKI about 4 years ago

続いて(2)です。

gc.cのstack_check()の役割としては
「lev(gc_mark()に渡される引数)がGC_LEVEL_MAX(250)の範囲でgc_mark()
を呼び出せるほどの余りがマシンスタックにあるかチェックする」
のように読めます。

static int
stack_check(void)
{
...
SET_STACK_END;
ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;

ただ、GC_WATER_MARKが512しかないので、そのチェックがうまくいってません。
GC_WATER_MARK = (gc_mark()フレームサイズ + gc_mark_children()フレームサイズ) * GC_LEVEL_MAX
となるべきだと思います。

私の環境(Linux 2.6.39-0-generic x86_64, gcc 4.5.2)ではgc_mark()と
gc_mark_children()のフレームが28ワードだったので、とりあえず以下のよう
に修正したいのですが、どうでしょうか?

この場合、GC_WATER_MARKは7000(64bit環境だと56KB)になります。
本当はgc_mark()の際に毎回stack_check()するのがいいと思うのですが、
そうするとGCの性能が落ちてしまうので、大体で決めてしまうしかないのか
なと思ってます。

GC用に56KB必要だとすると、Fiberでスタックが64KBしかつくらないのは
ダメじゃないかという気がするんですが、大丈夫でしょうか。CPUが64bitの
ときはアドレス空間サイズに余裕があるので64KBなんてケチケチしたことは
やめるべきだと思います。
32bitのときに、実質スタック36KB(64KB - 28KB)で足りるかどうかは、ささださんの
見解がほしいですが、わたしは足りないんじゃないかと疑っています。ささださん、
どうでしょう?
あと、nariさん、32bit のときにGC_LEVEL_MAXへらすという処理をすると、ぎゃっ
となりそうな処理ってどのようなものでしょうか。獏とした意見でかまわないので
教えてもらえませんか。

すいません、疎いのでこのあたりのトレードオフの勘所がどうも把握できていません

#12 Updated by Motohiro KOSAKI about 4 years ago

続いて(2)です。

gc.cのstack_check()の役割としては
「lev(gc_mark()に渡される引数)がGC_LEVEL_MAX(250)の範囲でgc_mark()
を呼び出せるほどの余りがマシンスタックにあるかチェックする」
のように読めます。

static int
stack_check(void)
{
...
SET_STACK_END;
ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;

ただ、GC_WATER_MARKが512しかないので、そのチェックがうまくいってません。
GC_WATER_MARK = (gc_mark()フレームサイズ + gc_mark_children()フレームサイズ) * GC_LEVEL_MAX
となるべきだと思います。

私の環境(Linux 2.6.39-0-generic x86_64, gcc 4.5.2)ではgc_mark()と
gc_mark_children()のフレームが28ワードだったので、とりあえず以下のよう
に修正したいのですが、どうでしょうか?

この場合、GC_WATER_MARKは7000(64bit環境だと56KB)になります。
本当はgc_mark()の際に毎回stack_check()するのがいいと思うのですが、
そうするとGCの性能が落ちてしまうので、大体で決めてしまうしかないのか
なと思ってます。

GC用に56KB必要だとすると、Fiberでスタックが64KBしかつくらないのは
ダメじゃないかという気がするんですが、大丈夫でしょうか。CPUが64bitの
ときはアドレス空間サイズに余裕があるので64KBなんてケチケチしたことは
やめるべきだと思います。
32bitのときに、実質スタック36KB(64KB - 28KB)で足りるかどうかは、ささださんの
見解がほしいですが、わたしは足りないんじゃないかと疑っています。ささださん、
どうでしょう?
あと、nariさん、32bit のときにGC_LEVEL_MAXへらすという処理をすると、ぎゃっ
となりそうな処理ってどのようなものでしょうか。獏とした意見でかまわないので
教えてもらえませんか。

すいません、疎いのでこのあたりのトレードオフの勘所がどうも把握できていません

#13 Updated by Shyouhei Urabe about 4 years ago

(07/02/2011 02:04 PM), Narihiro Nakamura wrote:

このようなデータ構造を作る最小の再現コードを書こうと思ったのですが意外
と難しく断念しました…。

procとenvが繰り返してればいいなら

0x1_000_0000_0000.times.inject{|i,|Enumerator.new{i}}

とか...

#14 Updated by Shyouhei Urabe about 4 years ago

(07/02/2011 02:04 PM), Narihiro Nakamura wrote:

このようなデータ構造を作る最小の再現コードを書こうと思ったのですが意外
と難しく断念しました…。

procとenvが繰り返してればいいなら

0x1_000_0000_0000.times.inject{|i,|Enumerator.new{i}}

とか...

#15 Updated by Yusuke Endoh about 4 years ago

遠藤です。

# 以下、自信ありげに言っていますが、全く無いので間違ってたらすみません

2011年7月2日14:04 Narihiro Nakamura authornari@gmail.com:

gc.cのstack_check()の役割としては
「lev(gc_mark()に渡される引数)がGC_LEVEL_MAX(250)の範囲でgc_mark()
を呼び出せるほどの余りがマシンスタックにあるかチェックする」
のように読めます。

stack_check() は lev とか関係なく「現在からスタックを GC_WATER_MARK だけ
伸ばしても大丈夫か」をチェックするものだと思います。
で、スタック増加量が GC_WATER_MARK を超えそうになる毎に stack_check() を
再度呼ぶ、というのが期待されている使い方ではないでしょうか。なので、

ただ、GC_WATER_MARKが512しかないので、そのチェックがうまくいってません。
GC_WATER_MARK = (gc_mark()フレームサイズ + gc_mark_children()フレームサイズ) * GC_LEVEL_MAX
となるべきだと思います。

ではなく、

GC_WATER_MARK >= (gc_mark()フレームサイズ + gc_mark_children()フレームサイズ)

でよいと思います。

しかし、GC_WATER_MARK = 512 でこの条件は満たされているような気がします。
よって、本当の原因は別にあり、まだ特定出来ていないのではないでしょうか。

私の環境(Linux 2.6.39-0-generic x86_64, gcc 4.5.2)ではgc_mark()と
gc_mark_children()のフレームが28ワードだったので、とりあえず以下のよう
に修正したいのですが、どうでしょうか?

なのでこの修正は、とりあえず予備をもたせたから現象が収まっただけではないか
と思います。が、現象が収まり、大きな性能劣化等が起きないのなら、とりあえず
コミットすることに反対ではありません。

--
Yusuke Endoh mame@tsg.ne.jp

#16 Updated by Yusuke Endoh about 4 years ago

遠藤です。

# 以下、自信ありげに言っていますが、全く無いので間違ってたらすみません

2011年7月2日14:04 Narihiro Nakamura authornari@gmail.com:

gc.cのstack_check()の役割としては
「lev(gc_mark()に渡される引数)がGC_LEVEL_MAX(250)の範囲でgc_mark()
を呼び出せるほどの余りがマシンスタックにあるかチェックする」
のように読めます。

stack_check() は lev とか関係なく「現在からスタックを GC_WATER_MARK だけ
伸ばしても大丈夫か」をチェックするものだと思います。
で、スタック増加量が GC_WATER_MARK を超えそうになる毎に stack_check() を
再度呼ぶ、というのが期待されている使い方ではないでしょうか。なので、

ただ、GC_WATER_MARKが512しかないので、そのチェックがうまくいってません。
GC_WATER_MARK = (gc_mark()フレームサイズ + gc_mark_children()フレームサイズ) * GC_LEVEL_MAX
となるべきだと思います。

ではなく、

GC_WATER_MARK >= (gc_mark()フレームサイズ + gc_mark_children()フレームサイズ)

でよいと思います。

しかし、GC_WATER_MARK = 512 でこの条件は満たされているような気がします。
よって、本当の原因は別にあり、まだ特定出来ていないのではないでしょうか。

私の環境(Linux 2.6.39-0-generic x86_64, gcc 4.5.2)ではgc_mark()と
gc_mark_children()のフレームが28ワードだったので、とりあえず以下のよう
に修正したいのですが、どうでしょうか?

なのでこの修正は、とりあえず予備をもたせたから現象が収まっただけではないか
と思います。が、現象が収まり、大きな性能劣化等が起きないのなら、とりあえず
コミットすることに反対ではありません。

--
Yusuke Endoh mame@tsg.ne.jp

#17 Updated by Motohiro KOSAKI about 4 years ago

本当はgc_mark()の際に毎回stack_check()するのがいいと思うのですが、
そうするとGCの性能が落ちてしまうので、大体で決めてしまうしかないのか
なと思ってます。

ところで、これって測定済みですか?
stack_check()ってespを変数にmovして、引き算一発なので、なにがそんなに
遅いんだろうかと。
espに対するmovってきっと普通のmovとは違う処理が走ってるので mov eaxとかと
同じ速度が出せる気はまったくしませんが、所詮 gcって slow pathなので
そんなに効くかなぁ と

#18 Updated by Motohiro KOSAKI about 4 years ago

本当はgc_mark()の際に毎回stack_check()するのがいいと思うのですが、
そうするとGCの性能が落ちてしまうので、大体で決めてしまうしかないのか
なと思ってます。

ところで、これって測定済みですか?
stack_check()ってespを変数にmovして、引き算一発なので、なにがそんなに
遅いんだろうかと。
espに対するmovってきっと普通のmovとは違う処理が走ってるので mov eaxとかと
同じ速度が出せる気はまったくしませんが、所詮 gcって slow pathなので
そんなに効くかなぁ と

#19 Updated by Narihiro Nakamura about 4 years ago

nariです。

2011年7月2日19:29 KOSAKI Motohiro kosaki.motohiro@gmail.com:

本当はgc_mark()の際に毎回stack_check()するのがいいと思うのですが、
そうするとGCの性能が落ちてしまうので、大体で決めてしまうしかないのか
なと思ってます。

ところで、これって測定済みですか?
stack_check()ってespを変数にmovして、引き算一発なので、なにがそんなに
遅いんだろうかと。
espに対するmovってきっと普通のmovとは違う処理が走ってるので mov eaxとかと
同じ速度が出せる気はまったくしませんが、所詮 gcって slow pathなので
そんなに効くかなぁ と

以下のパッチで測ってみました。

diff --git a/gc.c b/gc.c
index d5b8dfd..1709897 100644
--- a/gc.c
+++ b/gc.c
@@ -1614,7 +1614,7 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || stack_check()) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr;

以下のプログラムでGC時間を測ってみました。

GC::Profiler.enable
a = []
10000000.times{a << "a".dup}
p GC::Profiler.total_time

パッチ適用後: 1.410000000000001
バッチ適用前: 1.4899999999999998

と、4%くらい劣化してます。
これくらいなら入れしまっていいかもしれませんが。
うーん、バグ修正で4%も性能が落ちるのはなぁと正直悩んでます…。

--
Narihiro Nakamura (nari)

#20 Updated by Narihiro Nakamura about 4 years ago

nariです。

2011年7月2日19:29 KOSAKI Motohiro kosaki.motohiro@gmail.com:

本当はgc_mark()の際に毎回stack_check()するのがいいと思うのですが、
そうするとGCの性能が落ちてしまうので、大体で決めてしまうしかないのか
なと思ってます。

ところで、これって測定済みですか?
stack_check()ってespを変数にmovして、引き算一発なので、なにがそんなに
遅いんだろうかと。
espに対するmovってきっと普通のmovとは違う処理が走ってるので mov eaxとかと
同じ速度が出せる気はまったくしませんが、所詮 gcって slow pathなので
そんなに効くかなぁ と

以下のパッチで測ってみました。

diff --git a/gc.c b/gc.c
index d5b8dfd..1709897 100644
--- a/gc.c
+++ b/gc.c
@@ -1614,7 +1614,7 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || stack_check()) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr;

以下のプログラムでGC時間を測ってみました。

GC::Profiler.enable
a = []
10000000.times{a << "a".dup}
p GC::Profiler.total_time

パッチ適用後: 1.410000000000001
バッチ適用前: 1.4899999999999998

と、4%くらい劣化してます。
これくらいなら入れしまっていいかもしれませんが。
うーん、バグ修正で4%も性能が落ちるのはなぁと正直悩んでます…。

--
Narihiro Nakamura (nari)

#21 Updated by Motohiro KOSAKI about 4 years ago

GC::Profiler.enable
a = []
10000000.times{a << "a".dup}
p GC::Profiler.total_time

パッチ適用後: 1.410000000000001
バッチ適用前: 1.4899999999999998

と、4%くらい劣化してます。
これくらいなら入れしまっていいかもしれませんが。
うーん、バグ修正で4%も性能が落ちるのはなぁと正直悩んでます…。

おお、結構効きますね。こちらでも測ってみました。nariさんのに加えて
16段に一回だけチェックするようにしたやつ

trunk: 1.3090170000000483
nariパッチ: 1.3393349999998874
kosakiパッチ: 1.294899000000145

16に意味は全然ないのですが、何回かに一回だけチェックという論理で
オーバーヘッドはほぼ無視できるようです。
(元のより速くなってるのはたぶん測定誤差です。すいません)

~/ruby/trunk% svn diff
Index: gc.c
===================================================================
--- gc.c (revision 32355)
+++ gc.c (working copy)
@@ -1614,7 +1614,7 @@
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || (((lev&0xF)==0) && stack_check())) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr;

#22 Updated by Motohiro KOSAKI about 4 years ago

GC::Profiler.enable
a = []
10000000.times{a << "a".dup}
p GC::Profiler.total_time

パッチ適用後: 1.410000000000001
バッチ適用前: 1.4899999999999998

と、4%くらい劣化してます。
これくらいなら入れしまっていいかもしれませんが。
うーん、バグ修正で4%も性能が落ちるのはなぁと正直悩んでます…。

おお、結構効きますね。こちらでも測ってみました。nariさんのに加えて
16段に一回だけチェックするようにしたやつ

trunk: 1.3090170000000483
nariパッチ: 1.3393349999998874
kosakiパッチ: 1.294899000000145

16に意味は全然ないのですが、何回かに一回だけチェックという論理で
オーバーヘッドはほぼ無視できるようです。
(元のより速くなってるのはたぶん測定誤差です。すいません)

~/ruby/trunk% svn diff
Index: gc.c
===================================================================
--- gc.c (revision 32355)
+++ gc.c (working copy)
@@ -1614,7 +1614,7 @@
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || (((lev&0xF)==0) && stack_check())) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr;

#23 Updated by Kouhei Sutou about 4 years ago

須藤です。

In
" Re: [Ruby 1.9 - Bug #3781] FIBER_USE_NATIVE が有効だと落ちるスクリプトがある" on Sun, 3 Jul 2011 00:01:59 +0900,
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:

16に意味は全然ないのですが、何回かに一回だけチェックという論理で
オーバーヘッドはほぼ無視できるようです。
...
~/ruby/trunk% svn diff

Index: gc.c

--- gc.c (revision 32355)
+++ gc.c (working copy)
@@ -1614,7 +1614,7 @@
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || (((lev&0xF)==0) && stack_check())) {

16にそれほど意味がないなら、0xFで埋めこむよりは名前を付けて
おいた方が後から見た人が混乱しないかなぁと思いました。

(とりあえず、これで試してみましたという感じのコードかと思い
ますが。。。)

#24 Updated by Kouhei Sutou about 4 years ago

須藤です。

In
" Re: [Ruby 1.9 - Bug #3781] FIBER_USE_NATIVE が有効だと落ちるスクリプトがある" on Sun, 3 Jul 2011 00:01:59 +0900,
KOSAKI Motohiro kosaki.motohiro@gmail.com wrote:

16に意味は全然ないのですが、何回かに一回だけチェックという論理で
オーバーヘッドはほぼ無視できるようです。
...
~/ruby/trunk% svn diff

Index: gc.c

--- gc.c (revision 32355)
+++ gc.c (working copy)
@@ -1614,7 +1614,7 @@
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || (((lev&0xF)==0) && stack_check())) {

16にそれほど意味がないなら、0xFで埋めこむよりは名前を付けて
おいた方が後から見た人が混乱しないかなぁと思いました。

(とりあえず、これで試してみましたという感じのコードかと思い
ますが。。。)

#25 Updated by Narihiro Nakamura about 4 years ago

nariです。

2011年7月3日0:01 KOSAKI Motohiro kosaki.motohiro@gmail.com:

GC::Profiler.enable
a = []
10000000.times{a << "a".dup}
p GC::Profiler.total_time

パッチ適用後: 1.410000000000001
バッチ適用前: 1.4899999999999998

と、4%くらい劣化してます。
これくらいなら入れしまっていいかもしれませんが。
うーん、バグ修正で4%も性能が落ちるのはなぁと正直悩んでます…。

おお、結構効きますね。こちらでも測ってみました。nariさんのに加えて
16段に一回だけチェックするようにしたやつ

trunk: 1.3090170000000483
nariパッチ: 1.3393349999998874
kosakiパッチ: 1.294899000000145

16に意味は全然ないのですが、何回かに一回だけチェックという論理で
オーバーヘッドはほぼ無視できるようです。
(元のより速くなってるのはたぶん測定誤差です。すいません)

~/ruby/trunk% svn diff

Index: gc.c

--- gc.c (revision 32355)
+++ gc.c (working copy)
@@ -1614,7 +1614,7 @@
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || (((lev&0xF)==0) && stack_check())) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr;

以下のベンチマークで測ってみました。

GC::Profiler.enable
a = []
def make_depth(b, lev)
return b << "a" if (lev-=1) <= 0
b << []; make_depth(b.first, lev)
return b
end
200000.times{a << make_depth([], 200)}
p GC::Profiler.total_time

trunk: 9.31
nariパッチ: 9.63
kosakiパッチ: 10.25

maskする分遅くなってしまうような気がします。

やはり、遠藤さんの仰ったように、stack_check()の引数にGC_WARTER_MARKを渡すように修正するのが
よさそうだと思っています。

--
Narihiro Nakamura (nari)

#26 Updated by Narihiro Nakamura about 4 years ago

nariです。

2011年7月3日0:01 KOSAKI Motohiro kosaki.motohiro@gmail.com:

GC::Profiler.enable
a = []
10000000.times{a << "a".dup}
p GC::Profiler.total_time

パッチ適用後: 1.410000000000001
バッチ適用前: 1.4899999999999998

と、4%くらい劣化してます。
これくらいなら入れしまっていいかもしれませんが。
うーん、バグ修正で4%も性能が落ちるのはなぁと正直悩んでます…。

おお、結構効きますね。こちらでも測ってみました。nariさんのに加えて
16段に一回だけチェックするようにしたやつ

trunk: 1.3090170000000483
nariパッチ: 1.3393349999998874
kosakiパッチ: 1.294899000000145

16に意味は全然ないのですが、何回かに一回だけチェックという論理で
オーバーヘッドはほぼ無視できるようです。
(元のより速くなってるのはたぶん測定誤差です。すいません)

~/ruby/trunk% svn diff

Index: gc.c

--- gc.c (revision 32355)
+++ gc.c (working copy)
@@ -1614,7 +1614,7 @@
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || (((lev&0xF)==0) && stack_check())) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr;

以下のベンチマークで測ってみました。

GC::Profiler.enable
a = []
def make_depth(b, lev)
return b << "a" if (lev-=1) <= 0
b << []; make_depth(b.first, lev)
return b
end
200000.times{a << make_depth([], 200)}
p GC::Profiler.total_time

trunk: 9.31
nariパッチ: 9.63
kosakiパッチ: 10.25

maskする分遅くなってしまうような気がします。

やはり、遠藤さんの仰ったように、stack_check()の引数にGC_WARTER_MARKを渡すように修正するのが
よさそうだと思っています。

--
Narihiro Nakamura (nari)

#27 Updated by Narihiro Nakamura about 4 years ago

nariです。

ちと話を整理させてください。
本件で、GCに関するバグを直す方法は今のところ以下の2つの案があります。

(1)gc_mark()時に必ずstack_check()を呼ぶようにする
(2)GC_WATER_MARKをlev<=GC_LEVEL_MAXまでgc_mark()を呼び出せる(おおまかな)サイズにする

(1)に関してはstack_check()の精度がよく、ギリギリまでマシンスタックを使
うことができますが、gc_mark()の速度低下を引き起こすので、駄目そうな気配
がしてます。

一方、(2)はstack_check()の精度が粗いのですが、gc_mark()の速度は変わりま
せん。また、Fiber以外の環境で普通にRubyを使ってる範囲では、ギリギリまで
マシンスタックを使うことはあまりないと思いますので、stack_check()を厳密
にやりすぎるのもどうかという気持ちもあります。

といったところで、速度面でも劣化がない(2)の修正をいれようと思うのですが
いかがでしょうか?

遠藤さんの仰ったような、stack_check()の引数にwater_markを入れるパッチを
作りました。本スレッドで上げてきたベンチマークプログラムの結果では性能
劣化はないことを確認しています。

diff --git a/gc.c b/gc.c
index d5b8dfd..d7b6fc3 100644
--- a/gc.c
+++ b/gc.c
@@ -1277,7 +1277,9 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
}
#endif

-#define GC_WATER_MARK 512
+#define GC_LEVEL_MAX 250
+#define MARK_CALL_FRAME_SIZE 28
+#define GC_WATER_MARK (GC_LEVEL_MAX * MARK_CALL_FRAME_SIZE)

size_t
ruby_stack_length(VALUE *p)
@@ -1289,28 +1291,30 @@ ruby_stack_length(VALUE *
p)
}

static int
-stack_check(void)
+stack_check(int water_mark)
{
int ret;
rb_thread_t th = GET_THREAD();
SET_STACK_END;
- ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;
+ ret = STACK_LENGTH > STACK_LEVEL_MAX - water_mark;
#ifdef __ia64
if (!ret) {
ret = (VALUE
)rb_ia64_bsp() - th->machine_register_stack_start >
- th->machine_register_stack_maxsize/sizeof(VALUE) - GC_WATER_MARK;
+ th->machine_register_stack_maxsize/sizeof(VALUE) - water_mark;
}
#endif
return ret;
}

+#define WATER_MARK 512
+
int
ruby_stack_check(void)
{
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
return 0;
#else
- return stack_check();
+ return stack_check(WATER_MARK);
#endif
}

@@ -1600,8 +1604,6 @@ rb_gc_mark_maybe(VALUE obj)
}
}

-#define GC_LEVEL_MAX 250
-
static void
gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
{
@@ -1614,7 +1616,7 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check(GC_WATER_MARK))) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr;

#28 Updated by Narihiro Nakamura about 4 years ago

nariです。

ちと話を整理させてください。
本件で、GCに関するバグを直す方法は今のところ以下の2つの案があります。

(1)gc_mark()時に必ずstack_check()を呼ぶようにする
(2)GC_WATER_MARKをlev<=GC_LEVEL_MAXまでgc_mark()を呼び出せる(おおまかな)サイズにする

(1)に関してはstack_check()の精度がよく、ギリギリまでマシンスタックを使
うことができますが、gc_mark()の速度低下を引き起こすので、駄目そうな気配
がしてます。

一方、(2)はstack_check()の精度が粗いのですが、gc_mark()の速度は変わりま
せん。また、Fiber以外の環境で普通にRubyを使ってる範囲では、ギリギリまで
マシンスタックを使うことはあまりないと思いますので、stack_check()を厳密
にやりすぎるのもどうかという気持ちもあります。

といったところで、速度面でも劣化がない(2)の修正をいれようと思うのですが
いかがでしょうか?

遠藤さんの仰ったような、stack_check()の引数にwater_markを入れるパッチを
作りました。本スレッドで上げてきたベンチマークプログラムの結果では性能
劣化はないことを確認しています。

diff --git a/gc.c b/gc.c
index d5b8dfd..d7b6fc3 100644
--- a/gc.c
+++ b/gc.c
@@ -1277,7 +1277,9 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
}
#endif

-#define GC_WATER_MARK 512
+#define GC_LEVEL_MAX 250
+#define MARK_CALL_FRAME_SIZE 28
+#define GC_WATER_MARK (GC_LEVEL_MAX * MARK_CALL_FRAME_SIZE)

size_t
ruby_stack_length(VALUE *p)
@@ -1289,28 +1291,30 @@ ruby_stack_length(VALUE *
p)
}

static int
-stack_check(void)
+stack_check(int water_mark)
{
int ret;
rb_thread_t th = GET_THREAD();
SET_STACK_END;
- ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;
+ ret = STACK_LENGTH > STACK_LEVEL_MAX - water_mark;
#ifdef __ia64
if (!ret) {
ret = (VALUE
)rb_ia64_bsp() - th->machine_register_stack_start >
- th->machine_register_stack_maxsize/sizeof(VALUE) - GC_WATER_MARK;
+ th->machine_register_stack_maxsize/sizeof(VALUE) - water_mark;
}
#endif
return ret;
}

+#define WATER_MARK 512
+
int
ruby_stack_check(void)
{
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
return 0;
#else
- return stack_check();
+ return stack_check(WATER_MARK);
#endif
}

@@ -1600,8 +1604,6 @@ rb_gc_mark_maybe(VALUE obj)
}
}

-#define GC_LEVEL_MAX 250
-
static void
gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
{
@@ -1614,7 +1616,7 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check(GC_WATER_MARK))) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr;

#29 Updated by Motohiro KOSAKI about 4 years ago

nariです。

ちと話を整理させてください。
本件で、GCに関するバグを直す方法は今のところ以下の2つの案があります。

(1)gc_mark()時に必ずstack_check()を呼ぶようにする
(2)GC_WATER_MARKをlev<=GC_LEVEL_MAXまでgc_mark()を呼び出せる(おおまかな)サイズにする

(1)に関してはstack_check()の精度がよく、ギリギリまでマシンスタックを使
うことができますが、gc_mark()の速度低下を引き起こすので、駄目そうな気配
がしてます。

一方、(2)はstack_check()の精度が粗いのですが、gc_mark()の速度は変わりま
せん。また、Fiber以外の環境で普通にRubyを使ってる範囲では、ギリギリまで
マシンスタックを使うことはあまりないと思いますので、stack_check()を厳密
にやりすぎるのもどうかという気持ちもあります。

といったところで、速度面でも劣化がない(2)の修正をいれようと思うのですが
いかがでしょうか?

いいと思います。
64bit 環境ではFiberのスタックを単に増やせばいいと思います。32bitではnative fiber
をやめるのと、最大fiber数減るの覚悟でスタック増やすのと二択ですけど、判断は
ささださんにおまかせしたい。

遠藤さんの仰ったような、stack_check()の引数にwater_markを入れるパッチを
作りました。本スレッドで上げてきたベンチマークプログラムの結果では性能
劣化はないことを確認しています。

diff --git a/gc.c b/gc.c
index d5b8dfd..d7b6fc3 100644
--- a/gc.c
+++ b/gc.c
@@ -1277,7 +1277,9 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
}
#endif

-#define GC_WATER_MARK 512
+#define GC_LEVEL_MAX 250
+#define MARK_CALL_FRAME_SIZE 28

28はあまりにもマジックナンバー過ぎるのでコメントを書くか、configureで似たような関数
コンパイルさせてみて計算するのがよいと思います。

+#define GC_WATER_MARK (GC_LEVEL_MAX * MARK_CALL_FRAME_SIZE)

size_t
ruby_stack_length(VALUE *p)
@@ -1289,28 +1291,30 @@ ruby_stack_length(VALUE *
p)
}

static int
-stack_check(void)
+stack_check(int water_mark)
{
int ret;
rb_thread_t th = GET_THREAD();
SET_STACK_END;
- ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;
+ ret = STACK_LENGTH > STACK_LEVEL_MAX - water_mark;
#ifdef __ia64
if (!ret) {
ret = (VALUE
)rb_ia64_bsp() - th->machine_register_stack_start >
- th->machine_register_stack_maxsize/sizeof(VALUE) - GC_WATER_MARK;
+ th->machine_register_stack_maxsize/sizeof(VALUE) - water_mark;
}
#endif
return ret;
}

+#define WATER_MARK 512
+

GC_WATER_MARKが存在するファイルで、WATER_MARKというdefineがでてくるのは
ひどいと思います。

int
ruby_stack_check(void)
{
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
return 0;
#else
- return stack_check();
+ return stack_check(WATER_MARK);
#endif
}

今気づいたのですが、この関数の仮定がFiberで成立してない気がします。
なかださんか、ささださんに言うべきだけど。
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
の場合は、sigsegv()ハンドラで実際にSIGSEGVが配送されてからsysstack_errorをraiseするかどうか
決めてるけど、ここで判定に失敗してsysstackではなくrb_bugのほうに行ってしまうのもバグっぽい
気がします。FiberでGC以外が原因でstackあふれたときに同じくSEGVしてしまうので。

#30 Updated by Motohiro KOSAKI about 4 years ago

nariです。

ちと話を整理させてください。
本件で、GCに関するバグを直す方法は今のところ以下の2つの案があります。

(1)gc_mark()時に必ずstack_check()を呼ぶようにする
(2)GC_WATER_MARKをlev<=GC_LEVEL_MAXまでgc_mark()を呼び出せる(おおまかな)サイズにする

(1)に関してはstack_check()の精度がよく、ギリギリまでマシンスタックを使
うことができますが、gc_mark()の速度低下を引き起こすので、駄目そうな気配
がしてます。

一方、(2)はstack_check()の精度が粗いのですが、gc_mark()の速度は変わりま
せん。また、Fiber以外の環境で普通にRubyを使ってる範囲では、ギリギリまで
マシンスタックを使うことはあまりないと思いますので、stack_check()を厳密
にやりすぎるのもどうかという気持ちもあります。

といったところで、速度面でも劣化がない(2)の修正をいれようと思うのですが
いかがでしょうか?

いいと思います。
64bit 環境ではFiberのスタックを単に増やせばいいと思います。32bitではnative fiber
をやめるのと、最大fiber数減るの覚悟でスタック増やすのと二択ですけど、判断は
ささださんにおまかせしたい。

遠藤さんの仰ったような、stack_check()の引数にwater_markを入れるパッチを
作りました。本スレッドで上げてきたベンチマークプログラムの結果では性能
劣化はないことを確認しています。

diff --git a/gc.c b/gc.c
index d5b8dfd..d7b6fc3 100644
--- a/gc.c
+++ b/gc.c
@@ -1277,7 +1277,9 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
}
#endif

-#define GC_WATER_MARK 512
+#define GC_LEVEL_MAX 250
+#define MARK_CALL_FRAME_SIZE 28

28はあまりにもマジックナンバー過ぎるのでコメントを書くか、configureで似たような関数
コンパイルさせてみて計算するのがよいと思います。

+#define GC_WATER_MARK (GC_LEVEL_MAX * MARK_CALL_FRAME_SIZE)

size_t
ruby_stack_length(VALUE *p)
@@ -1289,28 +1291,30 @@ ruby_stack_length(VALUE *
p)
}

static int
-stack_check(void)
+stack_check(int water_mark)
{
int ret;
rb_thread_t th = GET_THREAD();
SET_STACK_END;
- ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;
+ ret = STACK_LENGTH > STACK_LEVEL_MAX - water_mark;
#ifdef __ia64
if (!ret) {
ret = (VALUE
)rb_ia64_bsp() - th->machine_register_stack_start >
- th->machine_register_stack_maxsize/sizeof(VALUE) - GC_WATER_MARK;
+ th->machine_register_stack_maxsize/sizeof(VALUE) - water_mark;
}
#endif
return ret;
}

+#define WATER_MARK 512
+

GC_WATER_MARKが存在するファイルで、WATER_MARKというdefineがでてくるのは
ひどいと思います。

int
ruby_stack_check(void)
{
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
return 0;
#else
- return stack_check();
+ return stack_check(WATER_MARK);
#endif
}

今気づいたのですが、この関数の仮定がFiberで成立してない気がします。
なかださんか、ささださんに言うべきだけど。
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
の場合は、sigsegv()ハンドラで実際にSIGSEGVが配送されてからsysstack_errorをraiseするかどうか
決めてるけど、ここで判定に失敗してsysstackではなくrb_bugのほうに行ってしまうのもバグっぽい
気がします。FiberでGC以外が原因でstackあふれたときに同じくSEGVしてしまうので。

#31 Updated by Narihiro Nakamura about 4 years ago

nariです。

kosakiさん、パッチのレビュー、ありがとうございます。

指摘された箇所を直してみました。
# configure.inをいじるのは初めてだったのでその辺りは大分不安です。

diff --git a/configure.in b/configure.in
index 7f74fd1..6b08b2e 100644
--- a/configure.in
+++ b/configure.in
@@ -1227,6 +1227,63 @@ if test $rb_cv_stack_end_address != no; then
AC_DEFINE_UNQUOTED(STACK_END_ADDRESS, $rb_cv_stack_end_address)
fi

+AC_CACHE_CHECK(for gc_mark and gc_children stack frame approximate
size(word), rb_cv_gc_mark_stackframe_word,
+[save_CFLAGS="$CFLAGS"
+CFLAGS="-O0"
+AC_TRY_RUN([
+int word;
+void *stack_start;
+
+void
+set_stackframe_word()
+{
+ int dumy = 42;
+ int diff;
+
+ if (stack_start < (void *)&dumy) {
+ diff = (int)((void *)&dumy - stack_start);
+ }
+ else {
+ diff = (int)(stack_start - (void *)&dumy);
+ }
+ word = (diff/sizeof(void *));
+ if ((diff % sizeof(void *)) != 0) {
+ word++;
+ }
+}
+
+void
+gc_mark_children(void *p1, void *p2, int lev)
+{
+ void *obj = p2;
+
+ set_stackframe_word(p1,p2,lev);
+}
+
+void
+gc_mark(void *p1, void *p2, int lev)
+{
+ void *obj = p2;
+
+ gc_mark_children(p1,p2,lev++);
+}
+
+int
+main() {
+ int dumy = 42;
+
+ stack_start = (void *)&dumy;
+ gc_mark(0, 0, 255);
+ return word;
+}
+],
+ [rb_cv_gc_mark_stackframe_word="$?"],
+ [rb_cv_gc_mark_stackframe_word="$?"],
+ [rb_cv_gc_mark_stackframe_word="30"])
+CFLAGS="$save_CFLAGS"])
+AC_DEFINE_UNQUOTED(GC_MARK_STACKFRAME_WORD, $rb_cv_gc_mark_stackframe_word)
+
+
dnl Checks for library functions.
AC_TYPE_GETGROUPS
AC_TYPE_SIGNAL
diff --git a/gc.c b/gc.c
index d5b8dfd..bde9c53 100644
--- a/gc.c
+++ b/gc.c
@@ -1277,7 +1277,8 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
}
#endif

-#define GC_WATER_MARK 512
+#define GC_LEVEL_MAX 250
+#define STACKFRAME_FOR_GC_MARK (GC_LEVEL_MAX * GC_MARK_STACKFRAME_WORD)

size_t
ruby_stack_length(VALUE *p)
@@ -1289,28 +1290,30 @@ ruby_stack_length(VALUE *
p)
}

static int
-stack_check(void)
+stack_check(int water_mark)
{
int ret;
rb_thread_t th = GET_THREAD();
SET_STACK_END;
- ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;
+ ret = STACK_LENGTH > STACK_LEVEL_MAX - water_mark;
#ifdef __ia64
if (!ret) {
ret = (VALUE
)rb_ia64_bsp() - th->machine_register_stack_start >
- th->machine_register_stack_maxsize/sizeof(VALUE) - GC_WATER_MARK;
+ th->machine_register_stack_maxsize/sizeof(VALUE) - water_mark;
}
#endif
return ret;
}

+#define STACKFRAME_FOR_CALL_CFUNC 512
+
int
ruby_stack_check(void)
{
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
return 0;
#else
- return stack_check();
+ return stack_check(STACKFRAME_FOR_CALL_CFUNC);
#endif
}

@@ -1600,8 +1603,6 @@ rb_gc_mark_maybe(VALUE obj)
}
}

-#define GC_LEVEL_MAX 250
-
static void
gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
{
@@ -1614,7 +1615,7 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check(STACKFRAME_FOR_GC_MARK))) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr;

--
Narihiro Nakamura (nari)

#32 Updated by Narihiro Nakamura about 4 years ago

nariです。

kosakiさん、パッチのレビュー、ありがとうございます。

指摘された箇所を直してみました。
# configure.inをいじるのは初めてだったのでその辺りは大分不安です。

diff --git a/configure.in b/configure.in
index 7f74fd1..6b08b2e 100644
--- a/configure.in
+++ b/configure.in
@@ -1227,6 +1227,63 @@ if test $rb_cv_stack_end_address != no; then
AC_DEFINE_UNQUOTED(STACK_END_ADDRESS, $rb_cv_stack_end_address)
fi

+AC_CACHE_CHECK(for gc_mark and gc_children stack frame approximate
size(word), rb_cv_gc_mark_stackframe_word,
+[save_CFLAGS="$CFLAGS"
+CFLAGS="-O0"
+AC_TRY_RUN([
+int word;
+void *stack_start;
+
+void
+set_stackframe_word()
+{
+ int dumy = 42;
+ int diff;
+
+ if (stack_start < (void *)&dumy) {
+ diff = (int)((void *)&dumy - stack_start);
+ }
+ else {
+ diff = (int)(stack_start - (void *)&dumy);
+ }
+ word = (diff/sizeof(void *));
+ if ((diff % sizeof(void *)) != 0) {
+ word++;
+ }
+}
+
+void
+gc_mark_children(void *p1, void *p2, int lev)
+{
+ void *obj = p2;
+
+ set_stackframe_word(p1,p2,lev);
+}
+
+void
+gc_mark(void *p1, void *p2, int lev)
+{
+ void *obj = p2;
+
+ gc_mark_children(p1,p2,lev++);
+}
+
+int
+main() {
+ int dumy = 42;
+
+ stack_start = (void *)&dumy;
+ gc_mark(0, 0, 255);
+ return word;
+}
+],
+ [rb_cv_gc_mark_stackframe_word="$?"],
+ [rb_cv_gc_mark_stackframe_word="$?"],
+ [rb_cv_gc_mark_stackframe_word="30"])
+CFLAGS="$save_CFLAGS"])
+AC_DEFINE_UNQUOTED(GC_MARK_STACKFRAME_WORD, $rb_cv_gc_mark_stackframe_word)
+
+
dnl Checks for library functions.
AC_TYPE_GETGROUPS
AC_TYPE_SIGNAL
diff --git a/gc.c b/gc.c
index d5b8dfd..bde9c53 100644
--- a/gc.c
+++ b/gc.c
@@ -1277,7 +1277,8 @@ ruby_get_stack_grow_direction(volatile VALUE *addr)
}
#endif

-#define GC_WATER_MARK 512
+#define GC_LEVEL_MAX 250
+#define STACKFRAME_FOR_GC_MARK (GC_LEVEL_MAX * GC_MARK_STACKFRAME_WORD)

size_t
ruby_stack_length(VALUE *p)
@@ -1289,28 +1290,30 @@ ruby_stack_length(VALUE *
p)
}

static int
-stack_check(void)
+stack_check(int water_mark)
{
int ret;
rb_thread_t th = GET_THREAD();
SET_STACK_END;
- ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;
+ ret = STACK_LENGTH > STACK_LEVEL_MAX - water_mark;
#ifdef __ia64
if (!ret) {
ret = (VALUE
)rb_ia64_bsp() - th->machine_register_stack_start >
- th->machine_register_stack_maxsize/sizeof(VALUE) - GC_WATER_MARK;
+ th->machine_register_stack_maxsize/sizeof(VALUE) - water_mark;
}
#endif
return ret;
}

+#define STACKFRAME_FOR_CALL_CFUNC 512
+
int
ruby_stack_check(void)
{
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
return 0;
#else
- return stack_check();
+ return stack_check(STACKFRAME_FOR_CALL_CFUNC);
#endif
}

@@ -1600,8 +1603,6 @@ rb_gc_mark_maybe(VALUE obj)
}
}

-#define GC_LEVEL_MAX 250
-
static void
gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
{
@@ -1614,7 +1615,7 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
obj->as.basic.flags |= FL_MARK;
objspace->heap.live_num++;

  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
  • if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check(STACKFRAME_FOR_GC_MARK))) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { *mark_stack_ptr = ptr;

--
Narihiro Nakamura (nari)

#33 Updated by Motohiro KOSAKI about 4 years ago

int
ruby_stack_check(void)
{
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
return 0;
#else
- return stack_check();
+ return stack_check(WATER_MARK);
#endif
}

今気づいたのですが、この関数の仮定がFiberで成立してない気がします。
なかださんか、ささださんに言うべきだけど。
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
の場合は、sigsegv()ハンドラで実際にSIGSEGVが配送されてからsysstack_errorをraiseするかどうか
決めてるけど、ここで判定に失敗してsysstackではなくrb_bugのほうに行ってしまうのもバグっぽい
気がします。FiberでGC以外が原因でstackあふれたときに同じくSEGVしてしまうので。

すいません、これ誤報でした。
つい最近いれた、[Bug #1813] 対応でちゃんとraise sysstack するようになってました。
現在のtrunkだと、gc時にスタックつきやぶると gc -> sigsegv -> raise -> rb_newobj ->
gcネストで死亡 となります。なので、nariさんパッチですべて解決のようです。

#34 Updated by Motohiro KOSAKI about 4 years ago

int
ruby_stack_check(void)
{
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
return 0;
#else
- return stack_check();
+ return stack_check(WATER_MARK);
#endif
}

今気づいたのですが、この関数の仮定がFiberで成立してない気がします。
なかださんか、ささださんに言うべきだけど。
#if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)
の場合は、sigsegv()ハンドラで実際にSIGSEGVが配送されてからsysstack_errorをraiseするかどうか
決めてるけど、ここで判定に失敗してsysstackではなくrb_bugのほうに行ってしまうのもバグっぽい
気がします。FiberでGC以外が原因でstackあふれたときに同じくSEGVしてしまうので。

すいません、これ誤報でした。
つい最近いれた、[Bug #1813] 対応でちゃんとraise sysstack するようになってました。
現在のtrunkだと、gc時にスタックつきやぶると gc -> sigsegv -> raise -> rb_newobj ->
gcネストで死亡 となります。なので、nariさんパッチですべて解決のようです。

#35 Updated by Narihiro Nakamura about 4 years ago

  • % Done changed from 0 to 100
  • Status changed from Assigned to Closed

This issue was solved with changeset r32438.
Makoto, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • gc.c: change water_mark value value that may call
    gc_mark(lev <= GC_LEVEL_MAX) in gc_mark().
    In ruby_stack_check(), water_mark is a value that may call some
    C function. Fixes Bug #3781

  • configure.in: define GC_MARK_STACKFRAME_WORD that approximate
    size of gc_mark() and gc_mark_children() stackframes.

#36 Updated by Makoto Kishimoto about 4 years ago

  • Status changed from Closed to Open
  • File reduct.rbMagnifier added

すいません、気づいてなかったのですが、添付のスクリプトは今でも落ちます。
落ち方はちょっと変化していて、

~32419 当初の報告通り Segmentation fault

32420~32431 `resume': can't alloc machine stack to fiber (FiberError) で止まる。coreを吐いたりはしない

32432~ [BUG] object allocation during garbage collection phase で core を吐く

(ちょっとスクリプトを修正してるので添付し直します)

バックトレースは以下のような感じです

$ ~/ruby-working/ruby193/bin/ruby193 -v
ruby 1.9.4dev (2011-08-24 trunk 33043) [x86_64-freebsd8.2]

$ gdb ~/ruby-working/ruby193/bin/ruby193

GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...

(gdb) run --disable-gems reduct.rb

Starting program: /export/home/ksmakoto/ruby-working/ruby193/bin/ruby193 --disable-gems reduct.rb
[New LWP 100304]
[New Thread 8012041c0 (LWP 100304/initial thread)]
[New Thread 80120ae40 (LWP 100819/ruby193)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 8012041c0 (LWP 100304/initial thread)]
gc_mark_children (objspace=0x801247000, ptr=34379976960, lev=199) at ../ruby-git/gc.c:1627
1627 if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {

(gdb) bt

#0 gc_mark_children (objspace=0x801247000, ptr=34379976960, lev=199) at ../ruby-git/gc.c:1627
#1 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#2 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#3 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#4 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#5 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#6 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#7 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#8 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#9 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#10 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#11 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#12 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.

...(略)...

#190 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#191 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#192 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#193 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#194 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#195 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#196 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#197 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#198 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#199 0x00000008006bd73f in rb_gc_mark_locations (start=0x801592be0, end=Variable "end" is not available.
) at ../ruby-git/gc.c:1637
#200 0x00000008007b2cfe in env_mark (ptr=0x801584ec0) at ../ruby-git/vm.c:237
#201 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379982040, lev=1) at ../ruby-git/gc.c:1848
#202 0x00000008006abe47 in proc_mark (ptr=0x801583ab0) at ../ruby-git/proc.c:55
#203 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379979920, lev=2) at ../ruby-git/gc.c:1848
#204 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#205 0x00000008006bd73f in rb_gc_mark_locations (start=0x801595528, end=Variable "end" is not available.
) at ../ruby-git/gc.c:1637
#206 0x00000008007b2cfe in env_mark (ptr=0x8015a7a80) at ../ruby-git/vm.c:237
#207 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379979640, lev=1) at ../ruby-git/gc.c:1848
#208 0x00000008006abe47 in proc_mark (ptr=0x8015a6b50) at ../ruby-git/proc.c:55
#209 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379979560, lev=2) at ../ruby-git/gc.c:1848
#210 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#211 0x00000008006bd73f in rb_gc_mark_locations (start=0x801595460, end=Variable "end" is not available.
) at ../ruby-git/gc.c:1637
#212 0x00000008007b2cfe in env_mark (ptr=0x8015a7a00) at ../ruby-git/vm.c:237
#213 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379979520, lev=1) at ../ruby-git/gc.c:1848
#214 0x00000008006abe47 in proc_mark (ptr=0x8015a6290) at ../ruby-git/proc.c:55
#215 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379979440, lev=2) at ../ruby-git/gc.c:1848
#216 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#217 0x00000008006bd73f in rb_gc_mark_locations (start=0x801595280, end=Variable "end" is not available.
) at ../ruby-git/gc.c:1637
#218 0x00000008007b2cfe in env_mark (ptr=0x8015a7b80) at ../ruby-git/vm.c:237
#219 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379979880, lev=1) at ../ruby-git/gc.c:1848
#220 0x00000008006abe47 in proc_mark (ptr=0x8015a6880) at ../ruby-git/proc.c:55
#221 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379979800, lev=2) at ../ruby-git/gc.c:1848
#222 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#223 0x00000008006bd73f in rb_gc_mark_locations (start=0x80158c648, end=Variable "end" is not available.
) at ../ruby-git/gc.c:1637
#224 0x00000008007b2cfe in env_mark (ptr=0x801584f00) at ../ruby-git/vm.c:237
#225 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379988800, lev=1) at ../ruby-git/gc.c:1848
#226 0x00000008006abe47 in proc_mark (ptr=0x801583470) at ../ruby-git/proc.c:55
#227 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379986400, lev=2) at ../ruby-git/gc.c:1848
#228 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#229 0x00000008006bd73f in rb_gc_mark_locations (start=0x80158a040, end=Variable "end" is not available.
) at ../ruby-git/gc.c:1637
#230 0x00000008007b2cfe in env_mark (ptr=0x80149cdc0) at ../ruby-git/vm.c:237
#231 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379986840, lev=1) at ../ruby-git/gc.c:1848
#232 0x00000008006abe47 in proc_mark (ptr=0x8014edc90) at ../ruby-git/proc.c:55
#233 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379983000, lev=2) at ../ruby-git/gc.c:1848
#234 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#235 0x00000008006bd73f in rb_gc_mark_locations (start=0x801595678, end=Variable "end" is not available.
) at ../ruby-git/gc.c:1637
#236 0x00000008007b2cfe in env_mark (ptr=0x8015a7900) at ../ruby-git/vm.c:237
#237 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379982720, lev=1) at ../ruby-git/gc.c:1848
#238 0x00000008006abe47 in proc_mark (ptr=0x801583560) at ../ruby-git/proc.c:55
#239 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379982640, lev=2) at ../ruby-git/gc.c:1848
#240 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#241 0x00000008006bd73f in rb_gc_mark_locations (start=0x8015929a0, end=Variable "end" is not available.
) at ../ruby-git/gc.c:1637
#242 0x00000008007b2cfe in env_mark (ptr=0x801584f40) at ../ruby-git/vm.c:237
#243 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379982600, lev=1) at ../ruby-git/gc.c:1848
#244 0x00000008006abe47 in proc_mark (ptr=0x8015835b0) at ../ruby-git/proc.c:55
#245 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379982520, lev=2) at ../ruby-git/gc.c:1848
#246 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#247 0x00000008006bd73f in rb_gc_mark_locations (start=0x80158c670, end=Variable "end" is not available.
) at ../ruby-git/gc.c:1637
#248 0x00000008007b2cfe in env_mark (ptr=0x801584b40) at ../ruby-git/vm.c:237
#249 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379982960, lev=1) at ../ruby-git/gc.c:1848
#250 0x00000008006abe47 in proc_mark (ptr=0x8015834c0) at ../ruby-git/proc.c:55
#251 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34379982880, lev=2) at ../ruby-git/gc.c:1848
#252 0x00000008006bc4be in gc_mark_children (objspace=0x801247000, ptr=Variable "ptr" is not available.
) at ../ruby-git/gc.c:1637
#253 0x00000008006bd73f in rb_gc_mark_locations (start=0x801585308, end=Variable "end" is not available.
) at ../ruby-git/gc.c:1637
#254 0x00000008007b2cfe in env_mark (ptr=0x801585340) at ../ruby-git/vm.c:237
#255 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34380072680, lev=1) at ../ruby-git/gc.c:1848
#256 0x00000008006abdb5 in binding_mark (ptr=0x801444760) at ../ruby-git/proc.c:258
#257 0x00000008006bc04c in gc_mark_children (objspace=0x801247000, ptr=34380297000, lev=12) at ../ruby-git/gc.c:1848
#258 0x00000008006bd38e in mark_const_entry_i (key=Variable "key" is not available.
) at ../ruby-git/gc.c:1637
#259 0x000000080075ffb6 in st_foreach (table=0x8013bc280, func=0x8006bd2b0 , arg=34393407264) at ../ruby-git/st.c:787
#260 0x00000008006bc2b0 in gc_mark_children (objspace=0x801247000, ptr=34380372760, lev=11) at ../ruby-git/gc.c:1582
#261 0x00000008006bcdbe in mark_entry (key=Variable "key" is not available.
) at ../ruby-git/gc.c:1637
#262 0x000000080075ff50 in st_foreach (table=0x8013bc5b0, func=0x8006bcce0 , arg=34393407536) at ../ruby-git/st.c:747
#263 0x00000008006bc617 in gc_mark_children (objspace=0x801247000, ptr=34380372400, lev=10) at ../ruby-git/gc.c:1454
#264 0x00000008006bcdbe in mark_entry (key=Variable "key" is not available.
) at ../ruby-git/gc.c:1637
#265 0x000000080075ff50 in st_foreach (table=0x8013bc730, func=0x8006bcce0 , arg=34393407808) at ../ruby-git/st.c:747
#266 0x00000008006bc617 in gc_mark_children (objspace=0x801247000, ptr=34380372240, lev=9) at ../ruby-git/gc.c:1454
#267 0x00000008006bb573 in gc_mark_children (objspace=0x801247000, ptr=34380372440, lev=8) at ../ruby-git/gc.c:1637
#268 0x00000008006bb573 in gc_mark_children (objspace=0x801247000, ptr=34380372680, lev=7) at ../ruby-git/gc.c:1637
#269 0x00000008006bcdbe in mark_entry (key=Variable "key" is not available.
) at ../ruby-git/gc.c:1637
#270 0x000000080075ff50 in st_foreach (table=0x8013bc4f0, func=0x8006bcce0 , arg=34393408464) at ../ruby-git/st.c:747
#271 0x00000008006bc617 in gc_mark_children (objspace=0x801247000, ptr=34380372480, lev=6) at ../ruby-git/gc.c:1454
#272 0x00000008006bcdbe in mark_entry (key=Variable "key" is not available.
) at ../ruby-git/gc.c:1637
#273 0x000000080075ff50 in st_foreach (table=0x8013bc670, func=0x8006bcce0 , arg=34393408736) at ../ruby-git/st.c:747
#274 0x00000008006bc617 in gc_mark_children (objspace=0x801247000, ptr=34380372320, lev=5) at ../ruby-git/gc.c:1454
#275 0x00000008006bb573 in gc_mark_children (objspace=0x801247000, ptr=34380301520, lev=4) at ../ruby-git/gc.c:1637
#276 0x00000008006bb573 in gc_mark_children (objspace=0x801247000, ptr=34380301560, lev=3) at ../ruby-git/gc.c:1637
#277 0x00000008006bb573 in gc_mark_children (objspace=0x801247000, ptr=34380301600, lev=2) at ../ruby-git/gc.c:1637
#278 0x00000008006bb573 in gc_mark_children (objspace=0x801247000, ptr=34380297080, lev=1) at ../ruby-git/gc.c:1637
#279 0x00000008006bdbe2 in gc_marks (objspace=0x801247000) at ../ruby-git/gc.c:2458
#280 0x00000008006bdece in garbage_collect (objspace=0x801247000) at ../ruby-git/gc.c:2511
#281 0x00000008006be8e2 in rb_newobj () at ../ruby-git/gc.c:1164
#282 0x00000008006ef386 in rb_class_allocate_instance (klass=34379992200) at ../ruby-git/object.c:1603
#283 0x00000008007c1bd8 in vm_call0 (th=0x801217300, recv=Variable "recv" is not available.
) at vm_eval.c:79
#284 0x00000008007c2979 in rb_funcall (recv=34379992200, mid=Variable "mid" is not available.
) at vm_eval.c:235
#285 0x00000008006efe63 in rb_obj_alloc (klass=Variable "klass" is not available.
) at ../ruby-git/object.c:1593
#286 0x00000008006eff01 in rb_class_new_instance (argc=0, argv=0x801eb6120, klass=Variable "klass" is not available.
) at ../ruby-git/object.c:1625
#287 0x00000008007c85fa in vm_call_method (th=0x801217300, cfp=0x801ebdc38, num=Variable "num" is not available.
) at vm_insnhelper.c:404
#288 0x00000008007bc00a in vm_exec_core (th=0x801217300, initial=Variable "initial" is not available.
) at insns.def:1012
#289 0x00000008007c09ee in vm_exec (th=0x801217300) at ../ruby-git/vm.c:1181
#290 0x00000008007c7e8d in invoke_block_from_c (th=0x801217300, block=0x80201f150, self=34379990080, argc=1, argv=Variable "argv" is not available.
) at ../ruby-git/vm.c:585
#291 0x00000008007c9464 in yield_under (under=Variable "under" is not available.
) at ../ruby-git/vm.c:608
#292 0x00000008007c962e in specific_eval (argc=0, argv=0x801eb6088, klass=34379989120, self=34379990080) at vm_eval.c:1267
#293 0x00000008007c85fa in vm_call_method (th=0x801217300, cfp=0x801ebdd98, num=Variable "num" is not available.
) at vm_insnhelper.c:404
#294 0x00000008007bc00a in vm_exec_core (th=0x801217300, initial=Variable "initial" is not available.
) at insns.def:1012
#295 0x00000008007c09ee in vm_exec (th=0x801217300) at ../ruby-git/vm.c:1181
#296 0x00000008007c7e8d in invoke_block_from_c (th=0x801217300, block=0x801ebdf20, self=34379990080, argc=0, argv=Variable "argv" is not available.
) at ../ruby-git/vm.c:585
#297 0x00000008007c90c8 in loop_i () at ../ruby-git/vm.c:615
#298 0x00000008006a7390 in rb_rescue2 (b_proc=0x8007c9090 , data1=0, r_proc=0, data2=0) at ../ruby-git/eval.c:637
#299 0x00000008007b40ce in rb_f_loop (self=34379990080) at vm_eval.c:846
#300 0x00000008007c85fa in vm_call_method (th=0x801217300, cfp=0x801ebdef8, num=Variable "num" is not available.
) at vm_insnhelper.c:404
#301 0x00000008007bc00a in vm_exec_core (th=0x801217300, initial=Variable "initial" is not available.
) at insns.def:1012
#302 0x00000008007c09ee in vm_exec (th=0x801217300) at ../ruby-git/vm.c:1181
#303 0x00000008007c7e8d in invoke_block_from_c (th=0x801217300, block=0x801e81600, self=34379990080, argc=0, argv=Variable "argv" is not available.
) at ../ruby-git/vm.c:585
#304 0x00000008007c827f in rb_vm_invoke_proc (th=0x801217300, proc=0x801e81600, self=34379990080, argc=0, argv=0x80201ff88, blockptr=0x0)
at ../ruby-git/vm.c:631
#305 0x00000008007d74e8 in rb_fiber_start () at ../ruby-git/cont.c:1140
#306 0x0000000800f26fc4 in makecontext () from /lib/libc.so.7
#307 0x0000000000000000 in ?? ()
#308 0x0000000000000000 in ?? ()
#309 0x0000000000000000 in ?? ()
#310 0x0000000000000000 in ?? ()
#311 0x0000000000000000 in ?? ()
#312 0x0000000000000000 in ?? ()
#313 0x0000000000000000 in ?? ()
Error accessing memory address 0x802020000: Bad address.

(gdb) q

The program is running. Exit anyway? (y or n) y

#37 Updated by Anonymous almost 4 years ago

  • Status changed from Open to Closed

This issue was solved with changeset r32438.
Makoto, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • gc.c: change water_mark value value that may call
    gc_mark(lev <= GC_LEVEL_MAX) in gc_mark().
    In ruby_stack_check(), water_mark is a value that may call some
    C function. Fixes Bug #3781

  • configure.in: define GC_MARK_STACKFRAME_WORD that approximate
    size of gc_mark() and gc_mark_children() stackframes.

#38 Updated by Narihiro Nakamura almost 4 years ago

  • Status changed from Closed to Open
  • % Done changed from 100 to 0

#39 Updated by Shyouhei Urabe over 3 years ago

  • Status changed from Open to Assigned

#40 Updated by Narihiro Nakamura almost 3 years ago

  • Status changed from Assigned to Closed

r37075 でなおったと思います。

Also available in: Atom PDF