From: "ktsj (Kazuki Tsujimoto)" Date: 2013-02-05T23:56:42+09:00 Subject: [ruby-dev:46924] [ruby-trunk - Bug #7774] IFUNC上のbinding呼び出しでSEGV Issue #7774 has been updated by ktsj (Kazuki Tsujimoto). rb_callccから呼ばれるrb_vm_stack_to_heapでも、 同様にIFUNCの対応が必要ということのようです。 以下のパッチで直りましたがどうでしょうか。 diff --git a/vm.c b/vm.c index ef5dd97..1429cce 100644 --- a/vm.c +++ b/vm.c @@ -556,7 +556,7 @@ void rb_vm_stack_to_heap(rb_thread_t *th) { rb_control_frame_t *cfp = th->cfp; - while ((cfp = rb_vm_get_ruby_level_next_cfp(th, cfp)) != 0) { + while ((cfp = rb_vm_get_binding_creatable_next_cfp(th, cfp)) != 0) { rb_vm_make_env_object(th, cfp); cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); } ---------------------------------------- Bug #7774: IFUNC上のbinding呼び出しでSEGV https://bugs.ruby-lang.org/issues/7774#change-35862 Author: ktsj (Kazuki Tsujimoto) Status: Closed Priority: High Assignee: ko1 (Koichi Sasada) Category: core Target version: 2.0.0 ruby -v: ruby 2.0.0dev (2013-02-03 trunk 39032) [x86_64-linux] =begin 辻本です。 以下のコードでSEGVします。 tp = TracePoint.new(:raise) do |tp| tp.binding end tp.enable @obj = Object.new class << @obj include Enumerable def each yield 1 end end @obj.zip({}) {} バックトレースは以下の通り。 #0 0x00007ffff6ef7445 in raise () from /lib/x86_64-linux-gnu/libc.so.6 #1 0x00007ffff6efabab in abort () from /lib/x86_64-linux-gnu/libc.so.6 #2 0x00005555555ad998 in rb_bug (fmt=0x55555573ecd7 "Segmentation fault") at error.c:309 #3 0x000055555567f32f in sigsegv (sig=11, info=0x555555a5aa70, ctx=0x555555a5a940) at signal.c:649 #4 #5 0x00005555556ea894 in VM_EP_LEP (ep=0xc) at vm.c:28 #6 0x00005555556ea8ec in VM_CF_LEP (cfp=0x7ffff6b08e80) at vm.c:44 #7 0x00005555556ea91f in VM_CF_BLOCK_PTR (cfp=0x7ffff6b08e80) at vm.c:56 #8 0x0000555555700f57 in check_block (th=0x5555559f0590) at vm.c:646 #9 0x0000555555700fff in vm_yield (th=0x5555559f0590, argc=1, argv=0x7fffffffba38) at vm.c:666 #10 0x00005555556fd6d3 in rb_yield_0 (argc=1, argv=0x7fffffffba38) at vm_eval.c:897 #11 0x00005555556fd70d in rb_yield (val=93824999078160) at vm_eval.c:907 #12 0x00005555555a63c4 in zip_i (val=3, memo=0x555555bdb960, argc=1, argv=0x7ffff6a09070) at enum.c:2001 ... binding呼び出しによって環境がヒープに移されますが、 IFUNC上のepがそれに追随できていないのが原因です。 以下の拡張ライブラリのコードでも再現させることができるので、 TracePointのバグというよりはVMのバグといえそうです。 static VALUE segv_i(VALUE i, VALUE ary, int argc, VALUE *argv) { rb_binding_new(); rb_yield(Qnil); return Qnil; } VALUE rb_segv(VALUE obj) { rb_block_call(obj, rb_intern("m"), 0, 0, segv_i, 0); return Qnil; } =end -- http://bugs.ruby-lang.org/