Bug #7802

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

Added by Brad Sumersford about 1 year ago. Updated about 1 year ago.

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

Description

Conditions:

  • rbensure(cb, cbargs, 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 rbfuncall(object, rbintern("try_method"), 0);
}

static VALUE
rubyEnsure(VALUE object) {
return rbfuncall(object, rbintern("ensured_method"), 0);
}

static VALUE
rubyEnsured(VALUE module, VALUE object) {

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

return result;
}

void Initensured() {
rb
definemethod(rbmKernel, "ensured", rubyEnsured, 1);

}

test_ensured.rb

require_relative 'ensured'

class TestObject
def trymethod
raise "error raised in rb
ensure"
end

def ensuredmethod
# 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 testensured.rb
after detect
error raised in rb
ensure

$ ruby testensured.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/RELEASEI386
$ 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 rbensure and does regular rbfuncalls to the Ruby stdlib.

Associated revisions

Revision 39156
Added by Nobuyoshi Nakada about 1 year ago

eval.c: preserve errinfo

  • eval.c (rbensure): preserve errinfo accross ensure proc before JUMPTAG(). [Bug #7802]

History

#1 Updated by Nobuyoshi Nakada about 1 year 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

  • eval.c (rbensure): preserve errinfo accross ensure proc before JUMPTAG(). [Bug #7802]

Also available in: Atom PDF