From: Kouichi Ushijima Date: 2008-09-01T21:56:30+09:00 Subject: [ruby-dev:36082] x86_64環境でMarshal.dumpの不具合 NTTレゾナントの牛島と申します。 x86_64環境でMarshal.dump/loadがうまく働かない現象に遭遇しましたので、報 告させていただきます。 再現コードを以下に示します。本来等しいはずのobjとobj1が等しくないと判定 されてしまいます。 --------- obj = Array.new(10000) do Time.now.to_i + (rand * 10).to_i end obj1 = Marshal.load(Marshal.dump(obj)) p obj1 == obj # ==> false! --------- 個々の要素を比較してみると、私の環境ではobj1[6449]以降の値が狂ってしまっ ています。Arrayの長さが短いときには発生しないところを見ると、どうやらGC が悪さをしているようです。 素人考えですが、marshal.cのw_object()のFIXNUMのdump処理で、一時的に生成 されたBignumオブジェクトがMarshal.dump中に解放されてしまうのが問題のよう な気がします。 -------- else if (FIXNUM_P(obj)) { #if SIZEOF_LONG <= 4 w_byte(TYPE_FIXNUM, arg); w_long(FIX2INT(obj), arg); #else if (RSHIFT((long)obj, 31) == 0 || RSHIFT((long)obj, 31) == -1) { w_byte(TYPE_FIXNUM, arg); w_long(FIX2LONG(obj), arg); } else { w_object(rb_int2big(FIX2LONG(obj)), arg, limit); ^^^^^^^^^^^^^^^^^^^^^^^^^ } #endif -------- 確認した環境は以下の通りです。 - Red Hat Enterprise Linux Server release 5.2 (Tikanga) Linux host 2.6.18-92.1.6.el5 #1 SMP Fri Jun 20 02:36:06 EDT 2008 x86_64 x86_64 x86_64 GNU/Linux - ruby 1.8.6 (2008-08-11 patchlevel 287) [x86_64-linux] 以上、よろしくお願いします。 -- NTTレゾナント(株) 技術マーケティング部 牛島 浩一 mailto:ushijima@nttr.co.jp