rjbのGC問題の解決
rt.jar内の全クラスをロードするとコアになる問題
- 途中でコア吐いて死にます。エラー情報はどうやって取るんだろう。
- それが問題。コア吐いてるのがrjbやRubyならどうにでもなるんだけど、jvmだと勘と推理。
- gdbしてみたけどGCでこけてる?よくわかんないです。
- がーそ。GCでこけてるといえば、99.99%はrjbのバグ(保護すべきオブジェクトを保護してない)ですね。
- これ、0.1.2では解決しているような気がしますがどうでしょう?
- 駄目でした。sunパッケージは無視してみようかなあ…駄目でした。rubyをデバッグオプション付きでコンパイルしたらもうちょっとわかるかも知れません。今ebanさんとこのバイナリを使用中なので。出しました。??()って何やねん。
(gdb) bt #0 0x1029c28b in ?? () #1 0x10030eda in rb_gc_mark () from /usr/local/bin/cygruby18.dll #2 0x10030b6b in rb_gc_mark_maybe () from /usr/local/bin/cygruby18.dll #3 0x10030a61 in rb_mark_tbl () from /usr/local/bin/cygruby18.dll #4 0x1007b3c7 in st_foreach () from /usr/local/bin/cygruby18.dll #5 0x10030a91 in mark_hash () from /usr/local/bin/cygruby18.dll #6 0x10030e72 in rb_gc_mark () from /usr/local/bin/cygruby18.dll #7 0x10030b6b in rb_gc_mark_maybe () from /usr/local/bin/cygruby18.dll #8 0x100309a2 in rb_source_filename () from /usr/local/bin/cygruby18.dll #9 0x10031aa6 in rb_gc () from /usr/local/bin/cygruby18.dll #10 0x1003064c in rb_newobj () from /usr/local/bin/cygruby18.dll #11 0x1003068c in rb_data_object_alloc () from /usr/local/bin/cygruby18.dll #12 0x003d5d4a in rjb!find_class () from /usr/local/lib/ruby/site_ruby/1.8/i386-cygwin/rjb.so #13 0x1002a1e7 in rb_throw () from /usr/local/bin/cygruby18.dll #14 0x1001d877 in rb_with_disable_interrupt () from /usr/local/bin/cygruby18.dll #15 0x1001e36a in rb_with_disable_interrupt () from /usr/local/bin/cygruby18.dll #16 0x1001857c in rb_Array () from /usr/local/bin/cygruby18.dll #17 0x1001799f in rb_Array () from /usr/local/bin/cygruby18.dll #18 0x1001bdcd in rb_iterator_p () from /usr/local/bin/cygruby18.dll #19 0x1001c187 in rb_yield () from /usr/local/bin/cygruby18.dll #20 0x1003d2e0 in rb_gets () from /usr/local/bin/cygruby18.dll #21 0x1002a1b8 in rb_throw () from /usr/local/bin/cygruby18.dll #22 0x1001d877 in rb_with_disable_interrupt () from /usr/local/bin/cygruby18.dll #23 0x1001e36a in rb_with_disable_interrupt () from /usr/local/bin/cygruby18.dll #24 0x1001857c in rb_Array () from /usr/local/bin/cygruby18.dll #25 0x100174e6 in rb_Array () from /usr/local/bin/cygruby18.dll #26 0x10013fce in ruby_init () from /usr/local/bin/cygruby18.dll #27 0x10014556 in ruby_exec () from /usr/local/bin/cygruby18.dll #28 0x100145b0 in ruby_run () from /usr/local/bin/cygruby18.dll
- テストOKです@ruby 1.8.2 (2004-09-17) [i386-cygwin]+rjb-0.1.4
解決編
全然、解決方法が見えないけど。
rjbでは定数を移入したjavaクラスにバインドしようと考えています。
しかし、移入したJavaクラスはRubyのクラス(T_CLAS)ではなくデータ(T_DATA)として実装しています。
このため、rb_define_const(klass, ...);の引数klassとしてRData構造体を送っていました。その結果、RClassを想定しているRubyは、RDataのマーク関数用スロットにインスタンス変数テーブル(iv_tbl)を設定し、定数を格納しています。
これでなんとなく動けるのはGCが始まるまでです。GCが始まるとGCは正しくRDataだと認識し、マーク関数としてiv_tblのアドレスへジャンプします。このアドレスにはコードはなくiv_tblがあるため、SEGVします。
1.が正しい実装かな。
0.1.4の実装
1.を選択した。ただし、ここで作成したクラスは中間的なものとして直接は見せない。したがって、以前のスクリプトとソースレベルで互換。
ただし、Rjb::Java_lang_Integerのように、importしたクラスはRjbモジュール内に定数として保持される。外部に見えるのは、ここで定義したクラスをラップしたオブジェクト(Ruby内部ではデータ)。
Keyword(s):
References:[RubyJavaブリッヂ]