From: Nikolai Lugovoi <nlugovoi@...> Date: 2009-09-24T23:24:56+09:00 Subject: [ruby-core:25748] Segfault with missing instance_method on module ruby 1.9.2dev, trunk 25073 [i686-linux] Sample code, that results in SIGSEGV, is a narrowed down version from Rails Actionpack: ----8<--------------- module Declarative def test(name, &block) test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym defined = instance_method(test_name) rescue false raise "#{test_name} is already defined in #{self}" if defined if block_given? define_method(test_name, &block) else define_method(test_name) do flunk "No implementation provided for #{name}" end end end end module FooBar extend Declarative test "should not segfault" do puts "OK" end end include FooBar test_should_not_segfault ----8<--------------- GDB output: ----8<--------------- Program received signal SIGSEGV, Segmentation fault. 0x0812db43 in rb_class_of (obj=6) at ./include/ruby/ruby.h:1236 1236 return RBASIC(obj)->klass; Missing separate debuginfos, use: debuginfo-install glibc-2.10.90-23.i686 nss-softokn-freebl-3.12.4-9.fc12.i686 (gdb) bt #0 0x0812db43 in rb_class_of (obj=6) at ./include/ruby/ruby.h:1236 #1 0x081391ed in rb_call0 (recv=6, mid=2863, argc=1, argv=0xbfffe6e0, scope=CALL_FCALL, self=6) at vm_eval.c:212 #2 0x08139530 in rb_call (recv=6, mid=2863, argc=1, argv=0xbfffe6e0, scope=CALL_FCALL) at vm_eval.c:301 #3 0x081399df in rb_funcall (recv=6, mid=2863, n=1) at vm_eval.c:490 #4 0x0805dd83 in mnew (klass=136400260, obj=6, id=12056, mclass=136493140, scope=0) at proc.c:916 #5 0x0805e31e in rb_mod_instance_method (mod=136400260, vid=3086350) at proc.c:1193 #6 0x0812e243 in call_cfunc (func=0x805e2e3 <rb_mod_instance_method>, recv=136400260, len=1, argc=1, argv=0xb7d56048) at vm_insnhelper.c:292 #7 0x0812ebda in vm_call_cfunc (th=0x8202aa8, reg_cfp=0xb7dd5f2c, num=1, recv=136400260, blockptr=0x0, flag=8, me=0x8282d30) at vm_insnhelper.c:386 #8 0x0812f0e5 in vm_call_method (th=0x8202aa8, cfp=0xb7dd5f2c, num=1, blockptr=0x0, flag=8, id=8640, me=0x8282d30, recv=136400260) at vm_insnhelper.c:511 #9 0x08133467 in vm_exec_core (th=0x8202aa8, initial=0) at insns.def:994 #10 0x0813d74d in vm_exec (th=0x8202aa8) at vm.c:1117 #11 0x0813ddc8 in rb_iseq_eval_main (iseqval=136401280) at vm.c:1341 #12 0x0805b621 in ruby_exec_node (n=0x8215180, file=0x0) at eval.c:212 #13 0x0805b6a7 in ruby_run_node (n=0x8215180) at eval.c:240 #14 0x0805a38e in main (argc=2, argv=0xbffff364) at main.c:35 ----8<--------------- Workaround patch: ----8<--------------- diff --git a/proc.c b/proc.c index 3300ec9..c2e5f02 100644 --- a/proc.c +++ b/proc.c @@ -913,7 +913,7 @@ mnew(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope) VALUE sym = ID2SYM(id); if (!rb_method_basic_definition_p(klass, rmiss)) { - if (RTEST(rb_funcall(obj, rmiss, 1, sym))) { + if (Qundef != obj && RTEST(rb_funcall(obj, rmiss, 1, sym))) { return rb_proc_new(missing_wrap, rb_assoc_new(obj, sym)); } } ----8<---------------