[ruby-dev:25158] core dump on NetBSD 2.0
From:
Tanaka Akira <akr@...17n.org>
Date:
2004-12-11 17:32:35 UTC
List:
ruby-dev #25158
NetBSD 2.0 で次のようにすると core を吐きます。
Z:akr@netbsd20.vmw% ./ruby test/runner.rb test/rss
/home/akr/ruby/lib/ruby/1.9/rss/parser.rb:161: [BUG] Segmentation fault
ruby 1.9.0 (2004-12-11) [i386-netbsdelf2.0]
zsh: abort (core dumped) ./ruby test/runner.rb test/rss
Z:akr@netbsd20.vmw% gdb ruby ruby.core
GNU gdb 5.3nb1
Copyright 2002 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 "i386--netbsdelf"...
Core was generated by `ruby'.
Program terminated with signal 6, Aborted.
Reading symbols from /usr/libexec/ld.elf_so...done.
Loaded symbols for /usr/libexec/ld.elf_so
Reading symbols from /usr/lib/libcrypt.so.0...done.
Loaded symbols for /usr/lib/libcrypt.so.0
Reading symbols from /usr/lib/libm387.so.0...done.
Loaded symbols for /usr/lib/libm387.so.0
Reading symbols from /usr/lib/libm.so.0...done.
Loaded symbols for /usr/lib/libm.so.0
Reading symbols from /usr/lib/libc.so.12...done.
Loaded symbols for /usr/lib/libc.so.12
#0 0x48138fbb in kill () from /usr/lib/libc.so.12
(gdb) bt
#0 0x48138fbb in kill () from /usr/lib/libc.so.12
#1 0x481adbc3 in abort () from /usr/lib/libc.so.12
#2 0x080c0be8 in rb_bug (fmt=0x80e1f14 "Segmentation fault") at error.c:214
#3 0x080a3a3c in sigsegv (sig=11) at signal.c:446
#4 <signal handler called>
#5 st_lookup (table=0x0, key=3983, value=0xbfbf8698) at st.c:258
#6 0x08053d17 in search_method (klass=135299892, id=3983, origin=0xbfbf86c4)
at eval.c:380
#7 0x08053d61 in rb_get_method_body (klassp=0xbfbf8700, idp=0xbfbf8704,
noexp=0xbfbf86f0) at eval.c:401
#8 0x08053ef9 in rb_method_node (klass=135299892, id=3983) at eval.c:463
#9 0x0805a4bf in rb_respond_to (obj=135299952, id=6281) at eval.c:3942
#10 0x0808004c in convert_type (val=135299952, tname=0x80cdb21 "Array",
method=0x80e3961 "to_ary", raise=2) at object.c:2062
#11 0x08080119 in rb_convert_type (val=135299952, type=9,
tname=0x80cdb21 "Array", method=0x80e3961 "to_ary") at object.c:2087
#12 0x080b4c3e in to_ary (ary=135299952) at array.c:300
#13 0x080b735e in rb_ary_concat (x=135299972, y=135299952) at array.c:2457
#14 0x08059107 in rb_eval (self=135324492, n=0x83a2958) at eval.c:3149
#15 0x080587d5 in rb_eval (self=135324492, n=0x83a2930) at eval.c:3209
#16 0x0805cbe9 in rb_call0 (klass=135322872, recv=135324492, id=19489,
oid=19489, argc=0, argv=0xbfbf915c, body=0x83a2930, nosuper=0)
at eval.c:5688
---Type <return> to continue, or q <return> to quit---
#17 0x0805d294 in rb_call (klass=135322872, recv=135324492, mid=19489, argc=3,
argv=0xbfbf9150, scope=0) at eval.c:5781
#18 0x08058661 in rb_eval (self=138105700, n=0x83f28a4) at ruby.h:635
#19 0x0805b2bf in rb_yield_0 (val=137864020, self=138105700, klass=0, flags=0,
avalue=0) at eval.c:4755
#20 0x0805b892 in rb_yield (val=137864020) at eval.c:4837
#21 0x080b5d6b in rb_ary_each (ary=138343980) at array.c:1255
#22 0x080675eb in call_cfunc (func=0x80b5d44 <rb_ary_each>, recv=138343980,
len=0, argc=0, argv=0x0) at eval.c:5415
#23 0x0805d05d in rb_call0 (klass=135409092, recv=138343980, id=3865,
oid=3865, argc=0, argv=0x0, body=0x81229a0, nosuper=0) at eval.c:5559
#24 0x0805d294 in rb_call (klass=135409092, recv=138343980, mid=3865, argc=0,
argv=0x0, scope=0) at eval.c:5781
#25 0x08058661 in rb_eval (self=138105700, n=0x83f2f34) at ruby.h:635
#26 0x08057b94 in rb_eval (self=138105700, n=0x83f313c) at eval.c:2919
#27 0x0805a2af in module_setup (module=138105700, n=0x83efcd0) at eval.c:3917
#28 0x08059709 in rb_eval (self=135432632, n=0x83efcbc) at eval.c:3853
#29 0x0805ea9b in rb_load (fname=137757740, wrap=0) at eval.c:6561
#30 0x0805f3ba in rb_require_safe (fname=137830720, safe=0) at eval.c:6878
#31 0x080675eb in call_cfunc (func=0x805eec8 <rb_f_require>, recv=135432632,
len=1, argc=1, argv=0xbfbfa920) at eval.c:5415
#32 0x0805d05d in rb_call0 (klass=135437452, recv=135432632, id=9401,
oid=9401, argc=1, argv=0xbfbfa920, body=0x811ad68, nosuper=0)
---Type <return> to continue, or q <return> to quit---
at eval.c:5559
#33 0x0805d294 in rb_call (klass=135437452, recv=135432632, mid=9401, argc=1,
argv=0xbfbfa920, scope=1) at eval.c:5781
#34 0x08058661 in rb_eval (self=135432632, n=0x8360a1c) at ruby.h:635
#35 0x0805ea9b in rb_load (fname=137830860, wrap=0) at eval.c:6561
#36 0x0805f3ba in rb_require_safe (fname=137833360, safe=0) at eval.c:6878
#37 0x080675eb in call_cfunc (func=0x805eec8 <rb_f_require>, recv=135432632,
len=1, argc=1, argv=0xbfbfb0a0) at eval.c:5415
#38 0x0805d05d in rb_call0 (klass=135437452, recv=135432632, id=9401,
oid=9401, argc=1, argv=0xbfbfb0a0, body=0x811ad68, nosuper=0)
at eval.c:5559
#39 0x0805d294 in rb_call (klass=135437452, recv=135432632, mid=9401, argc=1,
argv=0xbfbfb0a0, scope=1) at eval.c:5781
#40 0x08058661 in rb_eval (self=135432632, n=0x8372bf4) at ruby.h:635
#41 0x0805ea9b in rb_load (fname=137833800, wrap=0) at eval.c:6561
#42 0x0805f3ba in rb_require_safe (fname=137834080, safe=0) at eval.c:6878
#43 0x080675eb in call_cfunc (func=0x805eec8 <rb_f_require>, recv=136216604,
len=1, argc=1, argv=0xbfbfb840) at eval.c:5415
#44 0x0805d05d in rb_call0 (klass=135437452, recv=136216604, id=9401,
oid=9401, argc=1, argv=0xbfbfb840, body=0x811ad68, nosuper=0)
at eval.c:5559
#45 0x0805d294 in rb_call (klass=135437452, recv=136216604, mid=9401, argc=1,
argv=0xbfbfb840, scope=1) at eval.c:5781
---Type <return> to continue, or q <return> to quit---
#46 0x08058661 in rb_eval (self=136216604, n=0x81e5e0c) at ruby.h:635
#47 0x08057f82 in rb_eval (self=136216604, n=0x81e59d4) at eval.c:3055
#48 0x0805cbe9 in rb_call0 (klass=136201924, recv=136216604, id=13321,
oid=13321, argc=0, argv=0xbfbfc1cc, body=0x81e59d4, nosuper=0)
at eval.c:5688
#49 0x0805d294 in rb_call (klass=136201924, recv=136216604, mid=13321, argc=3,
argv=0xbfbfc1c0, scope=1) at eval.c:5781
#50 0x08058661 in rb_eval (self=136216604, n=0x81e630c) at ruby.h:635
#51 0x0805b2bf in rb_yield_0 (val=136201244, self=136216604, klass=0, flags=0,
avalue=0) at eval.c:4755
#52 0x0805b892 in rb_yield (val=136201244) at eval.c:4837
#53 0x080b5d6b in rb_ary_each (ary=136201404) at array.c:1255
#54 0x080675eb in call_cfunc (func=0x80b5d44 <rb_ary_each>, recv=136201404,
len=0, argc=0, argv=0x0) at eval.c:5415
#55 0x0805d05d in rb_call0 (klass=135409092, recv=136201404, id=3865,
oid=3865, argc=0, argv=0x0, body=0x81229a0, nosuper=0) at eval.c:5559
#56 0x0805d294 in rb_call (klass=135409092, recv=136201404, mid=3865, argc=0,
argv=0x0, scope=0) at eval.c:5781
#57 0x08058661 in rb_eval (self=136216604, n=0x81e6b54) at ruby.h:635
#58 0x08057b94 in rb_eval (self=136216604, n=0x81e6208) at eval.c:2919
#59 0x0805cbe9 in rb_call0 (klass=136201924, recv=136216604, id=13249,
oid=13249, argc=0, argv=0xbfbfd2a8, body=0x81e6208, nosuper=0)
at eval.c:5688
---Type <return> to continue, or q <return> to quit---
#60 0x0805d294 in rb_call (klass=136201924, recv=136216604, mid=13249, argc=2,
argv=0xbfbfd2a0, scope=1) at eval.c:5781
#61 0x08058661 in rb_eval (self=136216604, n=0x81e7108) at ruby.h:635
#62 0x0805cbe9 in rb_call0 (klass=136201924, recv=136216604, id=3761,
oid=3761, argc=1, argv=0xbfbfd820, body=0x81e7108, nosuper=0)
at eval.c:5688
#63 0x0805d294 in rb_call (klass=136201924, recv=136216604, mid=3761, argc=1,
argv=0xbfbfd820, scope=0) at eval.c:5781
#64 0x08058661 in rb_eval (self=136250444, n=0x82180f0) at ruby.h:635
#65 0x0805b2bf in rb_yield_0 (val=136248764, self=136250444, klass=0, flags=2,
avalue=0) at eval.c:4755
#66 0x08061496 in proc_invoke (proc=136250044, args=136248764, self=6, klass=0)
at ruby.h:635
#67 0x08061569 in proc_call (proc=136250044, args=136216924) at eval.c:8317
#68 0x080675eb in call_cfunc (func=0x8061554 <proc_call>, recv=136250044,
len=-2, argc=1, argv=0xbfbfe0e0) at eval.c:5415
#69 0x0805d05d in rb_call0 (klass=135375652, recv=136250044, id=333, oid=333,
argc=1, argv=0xbfbfe0e0, body=0x811aa20, nosuper=0) at eval.c:5559
#70 0x0805d294 in rb_call (klass=135375652, recv=136250044, mid=333, argc=1,
argv=0xbfbfe0e0, scope=0) at eval.c:5781
#71 0x08058661 in rb_eval (self=136248764, n=0x82146e4) at ruby.h:635
#72 0x080580d5 in rb_eval (self=136248764, n=0x8214608) at eval.c:3400
#73 0x0805cbe9 in rb_call0 (klass=136250444, recv=136248764, id=5161,
---Type <return> to continue, or q <return> to quit---
oid=5161, argc=0, argv=0x0, body=0x8214608, nosuper=0) at eval.c:5688
#74 0x0805d294 in rb_call (klass=136250444, recv=136248764, mid=5161, argc=0,
argv=0x0, scope=0) at eval.c:5781
#75 0x08058661 in rb_eval (self=136250444, n=0x8219928) at ruby.h:635
#76 0x0805cbe9 in rb_call0 (klass=136250424, recv=136250444, id=5161,
oid=5161, argc=0, argv=0xbfbfefb8, body=0x8219928, nosuper=0)
at eval.c:5688
#77 0x0805d294 in rb_call (klass=136250424, recv=136250444, mid=5161, argc=2,
argv=0xbfbfefb0, scope=0) at eval.c:5781
#78 0x08058661 in rb_eval (self=135432632, n=0x8118f68) at ruby.h:635
#79 0x08058951 in rb_eval (self=135432632, n=0x81194f4) at ruby.h:664
#80 0x0805526c in ruby_exec_internal () at eval.c:1470
#81 0x08055288 in ruby_exec () at eval.c:1488
#82 0x080552c2 in ruby_run () at eval.c:1505
#83 0x080536dd in main (argc=3, argv=0xbfbff918, envp=0xbfbff928) at main.c:38
#84 0x08053462 in ___start ()
(gdb)
この SEGV 直前の garbage_collect での backtrace は次のようになっていま
す。
Z:akr@netbsd20.vmw% gdb ruby
GNU gdb 5.3nb1
Copyright 2002 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 "i386--netbsdelf"...
(gdb) break garbage_collect
Breakpoint 1 at 0x806cde1: file gc.c, line 1301.
(gdb) run test/runner.rb test/rss
Starting program: /home/akr/ruby/ruby/ruby test/runner.rb test/rss
Breakpoint 1, garbage_collect () at gc.c:1301
1301 if (dont_gc || during_gc) {
(gdb) c
Continuing.
Breakpoint 1, garbage_collect () at gc.c:1301
1301 if (dont_gc || during_gc) {
(gdb)
Continuing.
Breakpoint 1, garbage_collect () at gc.c:1301
1301 if (dont_gc || during_gc) {
(gdb)
Continuing.
Breakpoint 1, garbage_collect () at gc.c:1301
1301 if (dont_gc || during_gc) {
(gdb)
Continuing.
Breakpoint 1, garbage_collect () at gc.c:1301
1301 if (dont_gc || during_gc) {
(gdb)
Continuing.
Breakpoint 1, garbage_collect () at gc.c:1301
1301 if (dont_gc || during_gc) {
(gdb)
Continuing.
Breakpoint 1, garbage_collect () at gc.c:1301
1301 if (dont_gc || during_gc) {
(gdb) bt
#0 garbage_collect () at gc.c:1301
#1 0x0806be25 in rb_newobj () at gc.c:394
#2 0x080b4ae9 in ary_make_shared (ary=135239812) at array.c:245
#3 0x080b4b99 in ary_shared_array (klass=135406152, ary=135239812)
at array.c:267
#4 0x080b4bf0 in rb_values_from_ary (ary=135239812) at array.c:279
#5 0x080590fe in rb_eval (self=135324512, n=0x83a296c) at eval.c:3149
#6 0x080587d5 in rb_eval (self=135324512, n=0x83a2944) at eval.c:3209
#7 0x0805cbe9 in rb_call0 (klass=135323232, recv=135324512, id=19489,
oid=19489, argc=0, argv=0xbfbf914c, body=0x83a2944, nosuper=0)
at eval.c:5688
#8 0x0805d294 in rb_call (klass=135323232, recv=135324512, mid=19489, argc=3,
argv=0xbfbf9140, scope=0) at eval.c:5781
#9 0x08058661 in rb_eval (self=138105720, n=0x83f28b8) at ruby.h:635
#10 0x0805b2bf in rb_yield_0 (val=137864000, self=138105720, klass=0, flags=0,
avalue=0) at eval.c:4755
#11 0x0805b892 in rb_yield (val=137864000) at eval.c:4837
#12 0x080b5d6b in rb_ary_each (ary=138344000) at array.c:1255
#13 0x080675eb in call_cfunc (func=0x80b5d44 <rb_ary_each>, recv=138344000,
len=0, argc=0, argv=0x0) at eval.c:5415
#14 0x0805d05d in rb_call0 (klass=135409092, recv=138344000, id=3865,
oid=3865, argc=0, argv=0x0, body=0x81229a0, nosuper=0) at eval.c:5559
#15 0x0805d294 in rb_call (klass=135409092, recv=138344000, mid=3865, argc=0,
---Type <return> to continue, or q <return> to quit---
argv=0x0, scope=0) at eval.c:5781
#16 0x08058661 in rb_eval (self=138105720, n=0x83f2f48) at ruby.h:635
#17 0x08057b94 in rb_eval (self=138105720, n=0x83f3150) at eval.c:2919
#18 0x0805a2af in module_setup (module=138105720, n=0x83efce4) at eval.c:3917
#19 0x08059709 in rb_eval (self=135432632, n=0x83efcd0) at eval.c:3853
#20 0x0805ea9b in rb_load (fname=137757900, wrap=0) at eval.c:6561
#21 0x0805f3ba in rb_require_safe (fname=137830800, safe=0) at eval.c:6878
#22 0x080675eb in call_cfunc (func=0x805eec8 <rb_f_require>, recv=135432632,
len=1, argc=1, argv=0xbfbfa910) at eval.c:5415
#23 0x0805d05d in rb_call0 (klass=135437452, recv=135432632, id=9401,
oid=9401, argc=1, argv=0xbfbfa910, body=0x811ad68, nosuper=0)
at eval.c:5559
#24 0x0805d294 in rb_call (klass=135437452, recv=135432632, mid=9401, argc=1,
argv=0xbfbfa910, scope=1) at eval.c:5781
#25 0x08058661 in rb_eval (self=135432632, n=0x8360a58) at ruby.h:635
#26 0x0805ea9b in rb_load (fname=137830940, wrap=0) at eval.c:6561
#27 0x0805f3ba in rb_require_safe (fname=137833440, safe=0) at eval.c:6878
#28 0x080675eb in call_cfunc (func=0x805eec8 <rb_f_require>, recv=135432632,
len=1, argc=1, argv=0xbfbfb090) at eval.c:5415
#29 0x0805d05d in rb_call0 (klass=135437452, recv=135432632, id=9401,
oid=9401, argc=1, argv=0xbfbfb090, body=0x811ad68, nosuper=0)
at eval.c:5559
#30 0x0805d294 in rb_call (klass=135437452, recv=135432632, mid=9401, argc=1,
---Type <return> to continue, or q <return> to quit---
argv=0xbfbfb090, scope=1) at eval.c:5781
#31 0x08058661 in rb_eval (self=135432632, n=0x8372c30) at ruby.h:635
#32 0x0805ea9b in rb_load (fname=137833860, wrap=0) at eval.c:6561
#33 0x0805f3ba in rb_require_safe (fname=137834140, safe=0) at eval.c:6878
#34 0x080675eb in call_cfunc (func=0x805eec8 <rb_f_require>, recv=136216604,
len=1, argc=1, argv=0xbfbfb830) at eval.c:5415
#35 0x0805d05d in rb_call0 (klass=135437452, recv=136216604, id=9401,
oid=9401, argc=1, argv=0xbfbfb830, body=0x811ad68, nosuper=0)
at eval.c:5559
#36 0x0805d294 in rb_call (klass=135437452, recv=136216604, mid=9401, argc=1,
argv=0xbfbfb830, scope=1) at eval.c:5781
#37 0x08058661 in rb_eval (self=136216604, n=0x81e5e0c) at ruby.h:635
#38 0x08057f82 in rb_eval (self=136216604, n=0x81e59d4) at eval.c:3055
#39 0x0805cbe9 in rb_call0 (klass=136201924, recv=136216604, id=13321,
oid=13321, argc=0, argv=0xbfbfc1bc, body=0x81e59d4, nosuper=0)
at eval.c:5688
#40 0x0805d294 in rb_call (klass=136201924, recv=136216604, mid=13321, argc=3,
argv=0xbfbfc1b0, scope=1) at eval.c:5781
#41 0x08058661 in rb_eval (self=136216604, n=0x81e630c) at ruby.h:635
#42 0x0805b2bf in rb_yield_0 (val=136201244, self=136216604, klass=0, flags=0,
avalue=0) at eval.c:4755
#43 0x0805b892 in rb_yield (val=136201244) at eval.c:4837
#44 0x080b5d6b in rb_ary_each (ary=136201404) at array.c:1255
---Type <return> to continue, or q <return> to quit---
#45 0x080675eb in call_cfunc (func=0x80b5d44 <rb_ary_each>, recv=136201404,
len=0, argc=0, argv=0x0) at eval.c:5415
#46 0x0805d05d in rb_call0 (klass=135409092, recv=136201404, id=3865,
oid=3865, argc=0, argv=0x0, body=0x81229a0, nosuper=0) at eval.c:5559
#47 0x0805d294 in rb_call (klass=135409092, recv=136201404, mid=3865, argc=0,
argv=0x0, scope=0) at eval.c:5781
#48 0x08058661 in rb_eval (self=136216604, n=0x81e6b54) at ruby.h:635
#49 0x08057b94 in rb_eval (self=136216604, n=0x81e6208) at eval.c:2919
#50 0x0805cbe9 in rb_call0 (klass=136201924, recv=136216604, id=13249,
oid=13249, argc=0, argv=0xbfbfd298, body=0x81e6208, nosuper=0)
at eval.c:5688
#51 0x0805d294 in rb_call (klass=136201924, recv=136216604, mid=13249, argc=2,
argv=0xbfbfd290, scope=1) at eval.c:5781
#52 0x08058661 in rb_eval (self=136216604, n=0x81e7108) at ruby.h:635
#53 0x0805cbe9 in rb_call0 (klass=136201924, recv=136216604, id=3761,
oid=3761, argc=1, argv=0xbfbfd810, body=0x81e7108, nosuper=0)
at eval.c:5688
#54 0x0805d294 in rb_call (klass=136201924, recv=136216604, mid=3761, argc=1,
argv=0xbfbfd810, scope=0) at eval.c:5781
#55 0x08058661 in rb_eval (self=136250444, n=0x82180f0) at ruby.h:635
#56 0x0805b2bf in rb_yield_0 (val=136248764, self=136250444, klass=0, flags=2,
avalue=0) at eval.c:4755
#57 0x08061496 in proc_invoke (proc=136250044, args=136248764, self=6, klass=0)
---Type <return> to continue, or q <return> to quit---
at ruby.h:635
#58 0x08061569 in proc_call (proc=136250044, args=136216924) at eval.c:8317
#59 0x080675eb in call_cfunc (func=0x8061554 <proc_call>, recv=136250044,
len=-2, argc=1, argv=0xbfbfe0d0) at eval.c:5415
#60 0x0805d05d in rb_call0 (klass=135375652, recv=136250044, id=333, oid=333,
argc=1, argv=0xbfbfe0d0, body=0x811aa20, nosuper=0) at eval.c:5559
#61 0x0805d294 in rb_call (klass=135375652, recv=136250044, mid=333, argc=1,
argv=0xbfbfe0d0, scope=0) at eval.c:5781
#62 0x08058661 in rb_eval (self=136248764, n=0x82146e4) at ruby.h:635
#63 0x080580d5 in rb_eval (self=136248764, n=0x8214608) at eval.c:3400
#64 0x0805cbe9 in rb_call0 (klass=136250444, recv=136248764, id=5161,
oid=5161, argc=0, argv=0x0, body=0x8214608, nosuper=0) at eval.c:5688
#65 0x0805d294 in rb_call (klass=136250444, recv=136248764, mid=5161, argc=0,
argv=0x0, scope=0) at eval.c:5781
#66 0x08058661 in rb_eval (self=136250444, n=0x8219928) at ruby.h:635
#67 0x0805cbe9 in rb_call0 (klass=136250424, recv=136250444, id=5161,
oid=5161, argc=0, argv=0xbfbfefa8, body=0x8219928, nosuper=0)
at eval.c:5688
#68 0x0805d294 in rb_call (klass=136250424, recv=136250444, mid=5161, argc=2,
argv=0xbfbfefa0, scope=0) at eval.c:5781
#69 0x08058661 in rb_eval (self=135432632, n=0x8118f68) at ruby.h:635
#70 0x08058951 in rb_eval (self=135432632, n=0x81194f4) at ruby.h:664
#71 0x0805526c in ruby_exec_internal () at eval.c:1470
---Type <return> to continue, or q <return> to quit---
#72 0x08055288 in ruby_exec () at eval.c:1488
#73 0x080552c2 in ruby_run () at eval.c:1505
#74 0x080536dd in main (argc=3, argv=0xbfbff8fc, envp=0xbfbff90c) at main.c:38
#75 0x08053462 in ___start ()
(gdb)
この backtrace 内をいろいろ調べると、ary_shared_array 内の val が GC
されているのが問題で、val に volatile をつければ発症しなくなることがわ
かりました。
Index: array.c
===================================================================
RCS file: /src/ruby/array.c,v
retrieving revision 1.170
diff -u -r1.170 array.c
--- array.c 18 Nov 2004 03:45:23 -0000 1.170
+++ array.c 11 Dec 2004 17:01:45 -0000
@@ -262,7 +262,7 @@
ary_shared_array(klass, ary)
VALUE klass, ary;
{
- VALUE val = ary_alloc(klass);
+ volatile VALUE val = ary_alloc(klass);
ary_make_shared(ary);
RARRAY(val)->ptr = RARRAY(ary)->ptr;
しかし、なぜここに volatile をつけると発症しなくなるのか納得できないも
のがあったため、もうすこし調べてみました。volatile が必要になるのは普
通 GC を間接的に呼び出す関数呼び出しよりも後でその値を使っていないため
ですが、この場合は使っているため GC 中にはまだ値は残っているはずで、GC
で消えないはずなのです。
(volatile をつけていない版での) ary_alloc と ary_make_shared の呼び出
しの間はアセンブラでは次のようになっています。
call ary_alloc
movl %eax, %esi
.stabn 68,0,267,.LM115-ary_shared_array
.LM115:
movl %ebx, (%esp)
call ary_make_shared
つまり、間違って GC されてしまう val は ary_make_shared を呼ぶときには
ESI に保存されています。
そして、ary_make_shared, rb_newobj, garbage_collect と ESI をたどって
いくと、ary_make_shared, rb_newobj では ESI は変更されません。そして、
garbage_collect の先頭でスタックに保存され、ESI は他の用途に使用されま
す。
garbage_collect:
.stabn 68,0,1290,.LM505-garbage_collect
.LM505:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
subl $108, %esp
.stabn 68,0,1301,.LM506-garbage_collect
.LM506:
.LBB86:
movl dont_gc, %edi
testl %edi, %edi
.stabn 68,0,1294,.LM507-garbage_collect
.LM507:
movl %ebp, -108(%ebp)
.stabn 68,0,1301,.LM508-garbage_collect
.LM508:
jne .L547
movl during_gc, %esi
testl %esi, %esi
je .L546
...
そして garbage_collect ではスタックをスキャンして保守的 GC を行うわけ
ですが、残念なことにこのプッシュした val はスキャンする範囲から外れて
います。
なぜかというと、スタックの終端を求める SET_STACK_END は (この環境では)
# define SET_STACK_END VALUE *stack_end = __builtin_frame_address(0)
という定義で、garbage_collect の呼び出しフレームのフレームアドレスとなっ
ています。そして、この関数内でセーブしたレジスタはそのアドレスよりもさ
らにスタックの先端に近いため、範囲外になってしまうというわけです。
というわけで、とりあえずつぎの変更を行うと volatile を加えなくても落ち
ないようになりました。
Index: gc.c
===================================================================
RCS file: /src/ruby/gc.c,v
retrieving revision 1.192
diff -u -r1.192 gc.c
--- gc.c 10 Nov 2004 07:16:24 -0000 1.192
+++ gc.c 11 Dec 2004 17:28:03 -0000
@@ -434,7 +434,7 @@
# define SET_STACK_END VALUE stack_end; alloca(0);
# define STACK_END (&stack_end)
#else
-# if defined(__GNUC__) && defined(USE_BUILTIN_FRAME_ADDRESS) && !defined(__ia64__)
+# if defined(__GNUC__) && defined(USE_BUILTIN_FRAME_ADDRESS) && !defined(__ia64__) && 0
# define SET_STACK_END VALUE *stack_end = __builtin_frame_address(0)
# else
# define SET_STACK_END VALUE *stack_end = alloca(1)
でも、&& 0 をつけるのはコードの意図を尊重していないように思えます。
さて、どうしたものでしょう?
あと、gcc の version は次のとおりです。
Z:akr@netbsd20.vmw% gcc -v
Using built-in specs.
Configured with: /home/nick/work/netbsd/src/tools/gcc/../../gnu/dist/gcc/configure --enable-long-long --disable-multilib --enable-threads --disable-symvers --build=i386-unknown-netbsdelf --host=i386--netbsdelf --target=i386--netbsdelf
Thread model: posix
gcc version 3.3.3 (NetBSD nb3 20040520)
--
[田中 哲][たなか あきら][Tanaka Akira]