inabaです。

一箇所自分の間違いをみつけました。
前はAttrGetNextは3個の値を返してたのが仕様変更で今は2個になってたのにコードを修正してませんでした。

したがって、正しくは、ary = rb_ary_new2(2)にして、 rb_ary_push(ary, Qnil) を3回連続してるのを
2回にしました。しかし、これをやってもあいかわらず落ちてます。

Inaba,Touru wrote:
> まつもとさん、回答ありがとうございました。
>
> 変数の初期化あたりも見直したのですが、どうもよくわかりませんでした。
>
> ようやく問題になっている部分を追い込めたのは以下のようなコードでした。
>
>
> static VALUE AttrGetNext(VALUE obj0, VALUE db, VALUE obj,
>                             VALUE coverindex, VALUE key)
> {
>    VALUE ary, ary2;
>    char *in_key;
>    char *out_key;
>    AttrValueT value;
>    AttrValueT *valuep;
>    int i;
>    VALUE v;
>
>    assert((void *)db != NULL);
>    Check_Type(coverindex, T_FIXNUM);
>
>    ary = rb_ary_new2(3);
>
>    if (NIL_P(key))
>      in_key = NULL;
>    else {
>      Check_Type(key, T_STRING);
>      in_key = RSTRING_PTR(key);
>    }
>    // 以下がRubyから呼びたいCのライブラリ関数
>    out_key = (char *)AttrGetNext((dbT)db, NIL_P(obj) ? NULL : (dbObjT)obj,
>                                           FIX2INT(coverindex), in_key, &value);
>
>    if (out_key == NULL) {
>      rb_ary_push(ary, Qnil);
>      rb_ary_push(ary, Qnil);
>      rb_ary_push(ary, Qnil);
>    } else {
>      v = rb_class_new_instance(0, NULL, cAttrValue);
>      if (Qnil == v) {
>        fprintf(stderr, "failed rb_class_new_instance(0, NULL, cAttrValue)\n");
>        exit(1);
>      }
>      Data_Get_Struct(v, AttrValueT, valuep);
>
>      rb_ary_push(ary, rb_str_new2(out_key));
>      valuep->type = value.type;
>      switch(value.type) {
>      case ATTR_INT64:
>        valuep->u.i64value = value.u.i64value;
>        break;
>      case ATTR_INT:
>        valuep->u.ivalue = value.u.ivalue;
>        break;
>      case ATTR_FLOAT:
>        valuep->u.fvalue = value.u.fvalue;
>        break;
>      case ATTR_DOUBLE:
>        valuep->u.dvalue = value.u.dvalue;
>        break;
>      case ATTR_STRING:
>        valuep->u.svalue = value.u.svalue;
>        break;
>      case ATTR_MEMBLK:
>        valuep->u.mvalue.size = value.u.mvalue.size;
>        valuep->u.mvalue.data = value.u.mvalue.data;
>        for (i=0; i<value.u.mvalue.size; i++)
>          valuep->u.mvalue.data[i] = value.u.mvalue.data[i];
>        break;
>      default:
>        fprintf(stderr, "AttrNext: unknown type %x\n", value.type);
>        v = Qnil;
>        break;
>      }
>      rb_ary_push(ary, v);
>    }
>    return ary;
> }
>
> そしてrb_class_new_instanceで生成しているものの定義は以下のようなものです。
>
>
> /*-------------------------- AttrValueT class --------------------------*/
> static VALUE
> AttrValue_s_allocate(VALUE class)
> {
>    AttrValueT* p;
>
>    return Data_Make_Struct(class, AttrValueT, 0, 0, p);
> }
>
> static VALUE
> AttrValue_initialize(VALUE obj)
> {
>    AttrValueT *av;
>
>    Data_Get_Struct(obj, AttrValueT, av);
>    if (av == NULL) return Qnil;
>    else return obj;
> }
>
> (他のメソッド定義は略)
>
> 他でも似たようなクラスを同じように使っている部分は多いので、AttrGetNext で
> 三つの値を返すためにrb_ary_new2(3)で作った配列に積んでいるあたりが怪しいと見ているのですが
> いかがでしょうか?
>
> inaba
>
> Yukihiro Matsumoto wrote:
>> まつもと ゆきひろです
>>
>> 無視しているわけではないということを示すだけの返事です。
>>
>> rb_gc_mark()で落ちる原因はほぼ間違いなくどこかの変数の初期化
>> 漏れですが、それ以上のことは言えません。ライブラリをロードし
>> たことで落ちなくなるのは、初期化前にGCが呼ばれていたものが、
>> ライブラリのロードによってGCのタイミングがずれるからでしょう。
>>
>> これ以上はソースがないことにはなんとも。
>>
>> In message "Re: [ruby-ext:02341] Re: [BUG] rb_gc_mark()"
>>      on Wed, 21 Nov 2012 16:37:15 +0900, "Inaba,Touru" <inaba / lake.dti.ne.jp> writes:
>> |
>> |一週間ほど苦闘してきましたが、あいかわらずわかりません。
>> |Data_Make_Structを使っている付近は随分チェックしたのですが。
>> |いろいろvolatileを入れたりしてもだめ。
>> |
>> |一応あるところで rb_class_new_instance しているところで落ちているところまではわかったのですが、
>> |その原因のほうはさっぱり。
>> |
>> |さらにわけわからんのは、
>> |
>> |require "optparse"
>> |
>> |すると落ちなくなるという... optparseは全然使ってなくてもです。
>> |
>> |inaba
>>
>>
>
>
>