From: Nobuyoshi Nakada Date: 2010-10-29T23:25:05+09:00 Subject: [ruby-dev:42492] Re: memory profiler for test-all なかだです。 At Fri, 29 Oct 2010 03:05:07 +0900, SASADA Koichi wrote in [ruby-dev:42481]: > >  fiddle の箇所で SEGV します。ただ、fiddle だけで実行すると SEGV しな > > い。きちんと調べないと無理っぽいです。ObjectSpace.each_objects 相当をし > > ているので、誰かが変なオブジェクトを生成している、ってことだと思います。 > >  これは、この仕組みがうまく機能していなかっただけで、改訂版ではきっちり > test-all TESTS=fiddle で SEGV しました。 Fiddle::Closure#allocateがcifを初期化していないからのようです。 どこかでinitializeされないままのインスタンスがあるんでしょう。 これでSEGVします。 10000.times{ObjectSpace.memsize_of(Fiddle::Closure.allocate)} allocate()に MEMZERO(closure->cif, ffi_cif, 1) を入れるだけでも 落ちなくなりますが、そもそもcifをポインタにする必要もないように 見えます。 diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c index 5e9ede7..157b97c 100644 --- a/ext/fiddle/closure.c +++ b/ext/fiddle/closure.c @@ -5,7 +5,7 @@ VALUE cFiddleClosure; typedef struct { void * code; ffi_closure *pcl; - ffi_cif * cif; + ffi_cif cif; int argc; ffi_type **argv; } fiddle_closure; @@ -23,7 +23,6 @@ dealloc(void * ptr) #else munmap(cls->pcl, sizeof(cls->pcl)); #endif - xfree(cls->cif); if (cls->argv) xfree(cls->argv); xfree(cls); } @@ -37,7 +36,7 @@ closure_memsize(const void * ptr) if (ptr) { size += sizeof(*cls); #if !defined(FFI_NO_RAW_API) || !FFI_NO_RAW_API - size += ffi_raw_size(cls->cif); + size += ffi_raw_size(&cls->cif); #endif size += sizeof(*cls->argv); size += sizeof(ffi_closure); @@ -148,7 +147,6 @@ allocate(VALUE klass) closure->pcl = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); #endif - closure->cif = xmalloc(sizeof(ffi_cif)); return i; } @@ -185,7 +183,7 @@ initialize(int rbargc, VALUE argv[], VALUE self) rb_iv_set(self, "@ctype", ret); rb_iv_set(self, "@args", args); - cif = cl->cif; + cif = &cl->cif; pcl = cl->pcl; result = ffi_prep_cif(cif, NUM2INT(abi), argc, -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦