diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | eval.c | 4 | ||||
-rw-r--r-- | eval_intern.h | 2 | ||||
-rw-r--r-- | test/ruby/test_signal.rb | 25 | ||||
-rw-r--r-- | thread.c | 4 |
5 files changed, 36 insertions, 3 deletions
@@ -1,3 +1,7 @@ +Wed May 18 22:36:43 2011 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * eval.c (setup_exception): internal exception should be hidden + Wed May 18 20:25:04 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com> * lib/timeout.rb (Timeout#timeout): don't leak "execution expired" @@ -371,8 +371,10 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg) const char *file; volatile int line = 0; - if (NIL_P(mesg)) + if (NIL_P(mesg)) { mesg = th->errinfo; + if (INTERNAL_EXCEPTION_P(mesg)) JUMP_TAG(TAG_FATAL); + } if (NIL_P(mesg)) { mesg = rb_exc_new(rb_eRuntimeError, 0, 0); } diff --git a/eval_intern.h b/eval_intern.h index cacaa6c311..e1316bfce7 100644 --- a/eval_intern.h +++ b/eval_intern.h @@ -135,6 +135,8 @@ NORETURN(void _longjmp(jmp_buf, int)); #define JUMP_TAG(st) TH_JUMP_TAG(GET_THREAD(), (st)) +#define INTERNAL_EXCEPTION_P(exc) FIXNUM_P(exc) + enum ruby_tag_type { RUBY_TAG_RETURN = 0x1, RUBY_TAG_BREAK = 0x2, diff --git a/test/ruby/test_signal.rb b/test/ruby/test_signal.rb index 26e17b3b64..e3dd273fe1 100644 --- a/test/ruby/test_signal.rb +++ b/test/ruby/test_signal.rb @@ -1,5 +1,6 @@ require 'test/unit' require 'timeout' +require 'tempfile' require_relative 'envutil' class TestSignal < Test::Unit::TestCase @@ -195,4 +196,28 @@ class TestSignal < Test::Unit::TestCase w.close assert_equal(r.read, "foo") end + + def test_signal_requiring + t = Tempfile.new(%w"require_ensure_test .rb") + t.puts "sleep" + t.close + error = IO.popen([EnvUtil.rubybin, "-e", <<EOS, t.path, err: :close]) do |child| +th = Thread.new do + begin + require ARGV[0] + ensure + Marshal.dump($!, STDOUT) + end +end +STDOUT.puts +STDOUT.flush +th.join +EOS + child.gets + Process.kill("INT", child.pid) + Marshal.load(child) + end + t.close! + assert_nil(error) + end end @@ -70,8 +70,8 @@ static int rb_threadptr_dead(rb_thread_t *th); static void rb_check_deadlock(rb_vm_t *vm); -static const VALUE eKillSignal = INT2FIX(0); -static const VALUE eTerminateSignal = INT2FIX(1); +#define eKillSignal INT2FIX(0) +#define eTerminateSignal INT2FIX(1) static volatile int system_working = 1; #define closed_stream_error GET_VM()->special_exceptions[ruby_error_closed_stream] |