Bug #5439
closedBug #5350: WeakRef で謎の NoMethodError
r33361以降sample/test.rb:systemがFになる
Description
r33361の変更により、ccでコンパイルすると、プログラム終了時にfinalizerが呼ばれなくなり、sample/test.rb:system にFが出ます。
(Solaris 10, sparc, Sun Studio 11 にて確認)
% make test
(中略)
sample/test.rb:eval .............................
sample/test.rb:system .FFFF.F.
sample/test.rb:const .....
(中略)
sample/test.rb:path .......................
sample/test.rb:gc ....make: *** [yes-test-sample] Error 1
Fが出ているテストの1つは以下です。
test_ok(./miniruby -e 'print "foobar"'
== 'foobar')
r33361の変更で、以下の文が2か所に追加されています。
if (ATOMIC_SET(finalizing, 1)) return;
マクロ ATOMIC_SET() は、gccの場合(ただしWindows以外)、
define ATOMIC_SET(var, val) __sync_lock_test_and_set(&(var), (val))¶
に展開され、http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html によるとこの関数は
returns the previous contents of *ptr.
つまり、その変数に以前セットされていた値を返しますが、
gccおよびWIN32以外(Solarisのccなど)では、
define ATOMIC_SET(var, val) ((var) = (val))¶
に展開される、つまり、新しく代入した値を返すため、
if (ATOMIC_SET(finalizing, 1)) return;
は、ATOMIC_SET(finalizing, 1)が必ず1を返すため、常にreturnしてしまいます。
このため、多くのfinalizerが呼ばれないままプログラムが終了し、rb_io_fptr_finalizeなどで行われているバッファのフラッシュも行われないためFになったと推測します。