From 04ca48fc38f9d006e2711287f9576a606d0d269a Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 30 Nov 2013 08:46:41 +0000 Subject: eval.c: determine exit status and signal before finalization * 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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43930 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 ++++++ eval.c | 13 +++++++------ ext/-test-/exception/dataerror.c | 31 +++++++++++++++++++++++++++++++ test/-ext-/exception/test_data_error.rb | 14 ++++++++++++++ 4 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 ext/-test-/exception/dataerror.c create mode 100644 test/-ext-/exception/test_data_error.rb diff --git a/ChangeLog b/ChangeLog index 6c5f723e36..198e66170e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Sat Nov 30 17:46:35 2013 Nobuyoshi Nakada + + * 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 * enumerator.c (enumerator_with_index): should not store local variable diff --git a/eval.c b/eval.c index 15b0db2ce8..f3275ada0b 100644 --- a/eval.c +++ b/eval.c @@ -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 + +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 -- cgit v1.2.3