From: Tomoyuki Chikanaga Date: 2010-05-03T00:09:58+09:00 Subject: [ruby-dev:41131] [Bug #3236] ISeq.load で [BUG] iseq_set_sequence: ic_index overflow が発生 Bug #3236: ISeq.load で [BUG] iseq_set_sequence: ic_index overflow が発生 http://redmine.ruby-lang.org/issues/show/3236 起票者: Tomoyuki Chikanaga ステータス: Open, 優先度: Normal 担当者: Koichi Sasada, カテゴリ: YARV ruby -v: ruby 1.9.2dev (2010-05-02 trunk 27590) [x86_64-darwin10.3.0] RubyGems の iseq ライブラリを利用して、定数やインスタンス変数の参照を含むスクリプトをコンパイルしたものを load しようとすると以下のようなメッセージでエラーになります。 $ cat iseq_load.rb require "iseq" iseq = ISeq.compile("@a[0]") puts iseq.disasm ISeq.load(iseq.to_a) $ ruby-trunk -v iseq_load.rb ruby 1.9.2dev (2010-05-02 trunk 27590) [x86_64-darwin10.3.0] == disasm: @>========== 0000 trace 1 ( 1) 0002 getinstancevariable :@a, 0005 putobject 0 0007 opt_aref 0009 leave iseq_load.rb:5: [BUG] iseq_set_sequence: ic_index overflow: index: 2, size: 0 ruby 1.9.2dev (2010-05-02 trunk 27590) [x86_64-darwin10.3.0] -- control frame ---------- c:0004 p:---- s:0011 b:0011 l:000010 d:000010 CFUNC :load c:0003 p:0075 s:0007 b:0007 l:0014a8 d:000bc0 EVAL iseq_load.rb:5 c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH c:0001 p:0000 s:0002 b:0002 l:0014a8 d:0014a8 TOP --------------------------- -- Ruby level backtrace information ---------------------------------------- iseq_load.rb:5:in `
' iseq_load.rb:5:in `load' -- C level backtrace information ------------------------------------------- 0 ruby-trunk 0x0000000100177acb rb_vm_bugreport + 120 1 ruby-trunk 0x0000000100034f90 report_bug + 313 2 ruby-trunk 0x00000001000350b5 rb_bug + 241 3 ruby-trunk 0x000000010014a328 iseq_set_sequence + 2456 4 ruby-trunk 0x0000000100148f1c iseq_setup + 118 5 ruby-trunk 0x00000001001590e5 iseq_build_body + 2250 6 ruby-trunk 0x000000010015989f rb_iseq_build_from_ary + 1789 7 ruby-trunk 0x000000010015bbe3 iseq_load + 1788 8 ruby-trunk 0x000000010015bcb2 rb_iseq_load + 47 9 iseq.bundle 0x0000000100540eb5 iseq_s_load + 53 10 ruby-trunk 0x000000010016b040 call_cfunc + 282 11 ruby-trunk 0x000000010016aea7 vm_call_cfunc + 284 12 ruby-trunk 0x000000010016a07c vm_call_method + 373 13 ruby-trunk 0x0000000100164cae vm_exec_core + 11207 14 ruby-trunk 0x00000001001745e9 vm_exec + 147 15 ruby-trunk 0x0000000100174fca rb_iseq_eval_main + 45 16 ruby-trunk 0x0000000100039cd9 ruby_exec_internal + 193 17 ruby-trunk 0x0000000100039dfd ruby_exec_node + 30 18 ruby-trunk 0x0000000100039dd0 ruby_run_node + 56 19 ruby-trunk 0x0000000100000dcb main + 79 20 ruby-trunk 0x0000000100000d74 start + 52 21 ??? 0x0000000000000003 0x0 + 3 [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 配列から iseq を構築する時にインラインキャッシュのサイズ(ic_size)を復元していない為のようです。以下の修正で、make check でエラーが増えないことと、標準添付のライブラリ($prefix/lib/ruby/1.9.1/**/*.rb)が全て ISeq.load できることを確認しました。 ついでに、上記でひっかかっている ic_index と ic_size のチェックには等号が抜けているようでしたのでそれも追加しています。 Index: compile.c =================================================================== --- compile.c (revision 27590) +++ compile.c (working copy) @@ -1434,7 +1434,7 @@ { int ic_index = FIX2INT(operands[j]); IC ic = &iseq->ic_entries[ic_index]; - if (UNLIKELY(ic_index > iseq->ic_size)) { + if (UNLIKELY(ic_index >= iseq->ic_size)) { rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->ic_size); } @@ -5269,6 +5269,8 @@ break; case TS_IC: argv[j] = op; + if (NUM2INT(op) >= iseq->ic_size) + iseq->ic_size = NUM2INT(op) + 1; break; case TS_ID: argv[j] = rb_convert_type(op, T_SYMBOL, ---------------------------------------- http://redmine.ruby-lang.org