Project

General

Profile

Actions

Bug #7802

closed

Ruby crashes when detect is called while executing the ensure callback given to rb_ensure

Added by bladenkerst (Brad Sumersford) about 11 years ago. Updated about 11 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
1.9.3
Backport:
[ruby-core:52022]

Description

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.

Actions #1

Updated by nobu (Nobuyoshi Nakada) about 11 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r39156.
Brad, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


eval.c: preserve errinfo

Actions

Also available in: Atom PDF

Like0
Like0