morit****@razil*****
morit****@razil*****
2009年 9月 15日 (火) 13:58:09 JST
森です。
さらに手を入れて、grn_ctx_open()を提供することにしました。
これで、Groonga::Contextが完了した(grn_ctx_fin)後に、
grn_obj_closeが呼ばれても大丈夫になったと考えています。
ruby-groongaに下記のパッチを当てて、最新版のgroongaとリンクしますと、
私の環境ではSEGVが発生しなくなりました。ご確認いただければ幸いです。
Index: ext/rb-grn-object.c
===================================================================
--- ext/rb-grn-object.c (リビジョン 663)
+++ ext/rb-grn-object.c (作業コピー)
@@ -155,7 +155,7 @@
rb_grn_object->object = NULL;
debug("type: %x\n", grn_object->header.type);
if (rb_grn_object->need_close) {
- grn_obj_close(context, grn_object);
+ grn_obj_unlink(context, grn_object);
}
}
xfree(rb_grn_object);
Index: ext/rb-grn-context.c
===================================================================
--- ext/rb-grn-context.c (リビジョン 663)
+++ ext/rb-grn-context.c (作業コピー)
@@ -53,7 +53,7 @@
Data_Get_Struct(object, RbGrnContext, rb_grn_context);
if (!rb_grn_context)
rb_raise(rb_eGrnError, "groonga context is NULL");
- return &(rb_grn_context->context);
+ return (rb_grn_context->context);
}
static void
@@ -62,7 +62,7 @@
RbGrnContext *rb_grn_context = pointer;
grn_ctx *context;
- context = &(rb_grn_context->context);
+ context = (rb_grn_context->context);
debug("context-free: %p\n", context);
if (context->stat != GRN_CTX_FIN) {
grn_obj *database;
@@ -77,7 +77,6 @@
debug("context-free: %p: done\n", context);
xfree(rb_grn_context);
- GRN_CTX_USER_DATA(context)->ptr = NULL;
}
static VALUE
@@ -233,7 +232,6 @@
RbGrnContext *rb_grn_context;
grn_ctx *context;
int flags = 0;
- grn_rc rc;
VALUE options, default_options;
VALUE rb_encoding;
@@ -252,8 +250,7 @@
rb_grn_context = ALLOC(RbGrnContext);
DATA_PTR(self) = rb_grn_context;
- context = &(rb_grn_context->context);
- rc = grn_ctx_init(context, flags);
+ context = (rb_grn_context->context) = grn_ctx_open(flags);
rb_grn_context_check(context, self);
GRN_CTX_USER_DATA(context)->ptr = rb_grn_context;
Index: ext/rb-grn-expression.c
===================================================================
--- ext/rb-grn-expression.c (リビジョン 663)
+++ ext/rb-grn-expression.c (作業コピー)
@@ -245,6 +245,7 @@
if (rc != GRN_SUCCESS)
rb_grn_context_check(context,
rb_ary_new3(2, self, rb_ary_new4(argc, argv)));
+ grn_obj_close(context, default_column);
return Qnil;
}
Index: ext/rb-grn.h
===================================================================
--- ext/rb-grn.h (リビジョン 663)
+++ ext/rb-grn.h (作業コピー)
@@ -89,7 +89,7 @@
typedef struct _RbGrnContext RbGrnContext;
struct _RbGrnContext
{
- grn_ctx context;
+ grn_ctx *context;
};
typedef struct _RbGrnObject RbGrnObject;
>>> morit****@razil***** さんは書きました:
>
> 森です。
>
> groongaの方にも手を加え、grn_obj_unlinkが呼ばれたときにも
> finalizer関数を呼ぶようにしました。
>
> ruby-groongaに下記のパッチを当てて、最新版のgroongaとリンクしますと、
> groongaのカラムやテーブルオブジェクトがGCで回収されなくなります。
>
> しかし、元々の問題である、Groonga::Contextが完了した(grn_ctx_fin)後に、
> grn_obj_closeが呼ばれる問題については未解決です。
>
>
>
> Index: ext/rb-grn-object.c
> ===================================================================
> --- ext/rb-grn-object.c (リビジョン 663)
> +++ ext/rb-grn-object.c (作業コピー)
> @@ -155,7 +155,7 @@
> rb_grn_object->object = NULL;
> debug("type: %x\n", grn_object->header.type);
> if (rb_grn_object->need_close) {
> - grn_obj_close(context, grn_object);
> + grn_obj_unlink(context, grn_object);
> }
> }
> xfree(rb_grn_object);
> Index: ext/rb-grn-context.c
> ===================================================================
> --- ext/rb-grn-context.c (リビジョン 663)
> +++ ext/rb-grn-context.c (作業コピー)
> @@ -77,7 +77,6 @@
> debug("context-free: %p: done\n", context);
> xfree(rb_grn_context);
>
> - GRN_CTX_USER_DATA(context)->ptr = NULL;
> }
>
> static VALUE
>
>
> >>> morit****@razil***** さんは書きました:
> >
> > 森です。
> >
> > これは
> >
> > table.time("time")
> >
> > の行で生成されたgroongaのcolumnオブジェクトが、
> > sort処理の実行前にGCによってcloseされているのが直接の原因です。
> >
> > 少し根が深い問題で、少々手を加えただけでは解消しませんでした。
> >
> > >>> SHIDARA Yoji さんは書きました:
> > > daraです。
> > >
> > > > Groonga::Contextが完了した(grn_ctx_fin)後に、
> > > > そこから払い出されたobjectがclose(grn_obj_close)されているために、
> > > > free済みのメモリ領域が破壊されているようです。
> > > >
> > > > この事象がいつもrubyが終了するタイミングで出るのであれば、
> > > > それが原因かも知れません。
> > > >
> > > > うーん。。
> > >
> > > 何かのお役に立てるかわからないのですが、
> > > > 1000.times do |i|
> > > の直後に
> > > p i
> > > を挿入してどこまで回るかを見てみました。
> > > この場合、606までで死んでしまうことが多いようです(たまに完走することもあります)。
> > > #606で固まってしまい、SIGTERMを送っても止まらないこともありました。
> > > 以下は、gdbで606までで死んでしまった場合です:
> > >
> > > (中略)
> > > 603
> > > 604
> > > 605
> > > 606
> > >
> > > Program received signal SIGSEGV, Segmentation fault.
> > > [Switching to Thread 0x7f69597366e0 (LWP 7003)]
> > > 0x00007f69580bbd86 in grn_ra_ref (ctx=0x1d76480, ra=0x1dee0f0, id=1)
> > > at store.c:126
> > > 126 return (void *)(((byte *)p) + ((id & ra->element_mask) *
> > > ra->header->element_size));
> > > (gdb) bt
> > > #0 0x00007f69580bbd86 in grn_ra_ref (ctx=0x1d76480, ra=0x1dee0f0,
> > > id=1) at store.c:126
> > > #1 0x00007f695812ed58 in grn_obj_get_value_ (ctx=0x1d76480,
> > > obj=0x1dee0f0, id=1,
> > > size=0x7fff617415b4) at db.c:3939
> > > #2 0x00007f695812ca37 in grn_accessor_get_value_ (ctx=0x1d76480,
> > > a=0x54640a0, id=1,
> > > size=0x7fff617415b4) at db.c:3477
> > > #3 0x00007f695812ec53 in grn_obj_get_value_ (ctx=0x1d76480,
> > > obj=0x54640d0, id=1,
> > > size=0x7fff617415b4) at db.c:3917
> > > #4 0x00007f6958136636 in pack (ctx=0x1d76480, table=0x545d1b0,
> > > head=0x1d37ad0, tail=0x1d37ad0,
> > > keys=0x7fff61741830, n_keys=1) at db.c:5459
> > > #5 0x00007f69581377f1 in grn_table_sort (ctx=0x1d76480,
> > > table=0x545d1b0, offset=0, limit=1,
> > > result=0x1d6eef0, keys=0x7fff61741830, n_keys=1) at db.c:5702
> > > #6 0x00007f69583ee05e in rb_grn_table_sort (argc=<value optimized out>,
> > > argv=<value optimized out>, self=140090448633040)
> > > at /home/dara/local/src/ruby-groonga/ext/rb-grn-table.c:890
> > > #7 0x00007f69592626c2 in ?? () from /usr/lib/libruby1.8.so.1.8
> > > #8 0x00007f695926282a in ?? () from /usr/lib/libruby1.8.so.1.8
> > > #9 0x00007f695925c7e0 in ?? () from /usr/lib/libruby1.8.so.1.8
> > > #10 0x00007f69592609bb in ?? () from /usr/lib/libruby1.8.so.1.8
> > > #11 0x00007f6959289bd1 in ?? () from /usr/lib/libruby1.8.so.1.8
> > > #12 0x00007f69592626c2 in ?? () from /usr/lib/libruby1.8.so.1.8
> > > #13 0x00007f695926282a in ?? () from /usr/lib/libruby1.8.so.1.8
> > > #14 0x00007f695925c7e0 in ?? () from /usr/lib/libruby1.8.so.1.8
> > > #15 0x00007f695925ff80 in ?? () from /usr/lib/libruby1.8.so.1.8
> > > #16 0x00007f695926f67b in ?? () from /usr/lib/libruby1.8.so.1.8
> > > #17 0x00007f695926f6c5 in ruby_exec () from /usr/lib/libruby1.8.so.1.8
> > > #18 0x00007f695926f6f2 in ruby_run () from /usr/lib/libruby1.8.so.1.8
> > > #19 0x00000000004008b3 in main ()
> > >
> > > --
> > > SHIDARA Yoji
> > > 本を書きました! http://www.amazon.co.jp/dp/4798119881
> > >
> > --
> > morita
> >
> > _______________________________________________
> > groonga-dev mailing list
> > groon****@lists*****
> > http://lists.sourceforge.jp/mailman/listinfo/groonga-dev
> >
> --
> morita
>
> _______________________________________________
> groonga-dev mailing list
> groon****@lists*****
> http://lists.sourceforge.jp/mailman/listinfo/groonga-dev
>
--
morita