diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | eval.c | 13 | ||||
-rw-r--r-- | ext/-test-/exception/dataerror.c | 31 | ||||
-rw-r--r-- | test/-ext-/exception/test_data_error.rb | 14 |
4 files changed, 58 insertions, 6 deletions
@@ -1,3 +1,9 @@ +Sat Nov 30 17:46:35 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * eval.c (ruby_cleanup): determine exit status and signal to terminate + before finalization, to get rid of access destroyed T_DATA execption + object. [ruby-core:58643] [Bug #9167] + Sat Nov 30 16:25:14 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> * enumerator.c (enumerator_with_index): should not store local variable @@ -192,12 +192,6 @@ ruby_cleanup(volatile int ex) } th->errinfo = errs[1]; ex = error_handle(ex); - ruby_finalize_1(); - - /* unlock again if finalizer took mutexes. */ - rb_threadptr_unlock_all_locking_mutexes(GET_THREAD()); - POP_TAG(); - rb_thread_stop_timer_thread(1); #if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1 switch (ex) { @@ -232,6 +226,13 @@ ruby_cleanup(volatile int ex) ex = EXIT_FAILURE; } } + + ruby_finalize_1(); + + /* unlock again if finalizer took mutexes. */ + rb_threadptr_unlock_all_locking_mutexes(GET_THREAD()); + POP_TAG(); + rb_thread_stop_timer_thread(1); ruby_vm_destruct(GET_VM()); if (state) ruby_default_signal(state); diff --git a/ext/-test-/exception/dataerror.c b/ext/-test-/exception/dataerror.c new file mode 100644 index 0000000000..d8beba8aa4 --- /dev/null +++ b/ext/-test-/exception/dataerror.c @@ -0,0 +1,31 @@ +#include <ruby/ruby.h> + +static void +dataerror_mark(void *ptr) +{ + rb_gc_mark((VALUE)ptr); +} + +static void +dataerror_free(void *ptr) +{ +} + +static const rb_data_type_t dataerror_type = { + "Bug #9167", + {dataerror_mark, dataerror_free}, +}; + +static VALUE +dataerror_alloc(VALUE klass) +{ + VALUE n = rb_str_new_cstr("[Bug #9167] error"); + return TypedData_Wrap_Struct(klass, &dataerror_type, (void *)n); +} + +void +Init_dataerror(VALUE klass) +{ + VALUE rb_eDataErr = rb_define_class_under(klass, "DataError", rb_eStandardError); + rb_define_alloc_func(rb_eDataErr, dataerror_alloc); +} diff --git a/test/-ext-/exception/test_data_error.rb b/test/-ext-/exception/test_data_error.rb new file mode 100644 index 0000000000..140de5bd5a --- /dev/null +++ b/test/-ext-/exception/test_data_error.rb @@ -0,0 +1,14 @@ +require 'test/unit' +require_relative '../../ruby/envutil' + +module Bug + class TestException < Test::Unit::TestCase + def test_cleanup_data_error + bug9167 = '[ruby-core:58643] [Bug #9167]' + assert_normal_exit(<<-'end;', bug9167) # do + require '-test-/exception' + raise Bug::Exception::DataError, "Error" + end; + end + end +end |