From: Yukihiro Matsumoto Date: 2008-04-11T08:14:13+09:00 Subject: [ruby-dev:34323] Re: marshal_dump を使うとダンプ結果が壊れる まつもと ゆきひろです In message "Re: [ruby-dev:34312] marshal_dump を使うとダンプ結果が壊れる" on Thu, 10 Apr 2008 23:24:26 +0900, Tomoyuki Chikanaga writes: |1.8.6 において、marshal_dump / marshal_load を定義して |Marshal でのダンプを再定義したオブジェクトのダンプ結果が |不正になることがあります。 |複数のクラスのオブジェクト間で相互参照があって、サイズが |大きい時に発生します。 | |経緯は長くなるので端折りますと、どうやら marshal_dump で返した |オブジェクトが GC されてしまい、ダンプ処理の途中で中身が変化して |しまうようです。 |GC.disable すると発生しませんし、GC.stress を 1.9 から |バックポートしてみると発生しやすくなりました。 なるほど。 |一応以下のように修正すると発生しなくなるのを確認しました。 | |--- marshal.c.orig 2007-02-13 08:01:19.000000000 +0900 |+++ marshal.c. 2008-04-10 22:56:10.000000000 +0900 |@@ -502,7 +502,7 @@ | | st_add_direct(arg->data, obj, arg->data->num_entries); | if (rb_respond_to(obj, s_mdump)) { |- VALUE v; |+ volatile VALUE v; | | v = rb_funcall(obj, s_mdump, 0, 0); | w_class(TYPE_USRMARSHAL, obj, arg, Qfalse); | |ただこの v という変数は直後に w_object の引数に渡しているだけで、 |本来は volatile は不要だと理解しておりますので、問題は別のところに |あるのかもしれません。 最適化のレベルによってはvが消えてしまうのかもしれません。納 得はできないのですが、問題回避が先決でしょうから取り込みます。 1.9にも同様のパッチを当てておきます。 まつもと ゆきひろ /:|)