Issue #7802 has been reported by bladenkerst (Brad Sumersford).

----------------------------------------
Bug #7802: Ruby crashes when detect is called while executing the ensure callback given to rb_ensure
https://bugs.ruby-lang.org/issues/7802

Author: bladenkerst (Brad Sumersford)
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 
ruby -v: 1.9.3


Conditions:

- rb_ensure(cb, cb_args, ensure, ensure_args) is used from C API
- cb raises an exception
- ensure calls Enumerable#detect and detect finds an element

Sample code:

# ensured.c

#include "ruby.h"

static VALUE
rubyEnsuredBegin(VALUE object) {
  return rb_funcall(object, rb_intern("try_method"), 0);
}

static VALUE
rubyEnsure(VALUE object) {
  return rb_funcall(object, rb_intern("ensured_method"), 0);
}

static VALUE
rubyEnsured(VALUE module, VALUE object) {

  VALUE result = rb_ensure(
    rubyEnsuredBegin, object, 
    rubyEnsure, object
  );
 
  return result;
}

void Init_ensured() {
  rb_define_method(rb_mKernel, "ensured", rubyEnsured, 1);	
}

# test_ensured.rb

require_relative 'ensured'

class TestObject
  def try_method
    raise "error raised in rb_ensure"
  end
  
  def ensured_method
    # Returning true in the detect block will 
    # call rb_iter_break() which will cause
    # Ruby to crash when the exception resumes
    # unwinding the stack
    [1].detect { |i| ARGV[0] == 'crash' }
    
    # This line still gets executed
    puts 'after detect'
  end
end

begin
  ensured(TestObject.new)
rescue
  puts $!
end

__END__

$ ruby test_ensured.rb 
after detect
error raised in rb_ensure

$ ruby test_ensured.rb crash
after detect
test_ensured.rb: [BUG] Segmentation fault
ruby 1.9.3p385 (2013-02-06 revision 39114) [x86_64-darwin10.8.0]

-- Control frame information -----------------------------------------------
c:0004 p:0030 s:0009 b:0009 l:000398 d:000008 BLOCK 
c:0003 p:0047 s:0006 b:0006 l:000398 d:000b18 EVAL   test_ensured.rb:20
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:000398 d:000398 TOP 


Reproduced on the following system:
$ uname -a
Linux lion 2.6.32-5-686 #1 SMP Sun Sep 23 09:49:36 UTC 2012 i686 GNU/Linux
$ ruby -v
ruby 1.9.3p327 (2012-11-10 revision 37606) [i686-linux]

AND

$ uname -v
Darwin Kernel Version 10.8.0: Tue Jun  7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386
$ ruby -v
ruby 1.9.3p385 (2013-02-06 revision 39114) [x86_64-darwin10.8.0]

The use case for the above example is testing a C extension with Mocha (or other mocking library) that uses rb_ensure and does regular rb_funcalls to the Ruby stdlib.


-- 
http://bugs.ruby-lang.org/