ruby-changes:34926
From: nagachika <ko1@a...>
Date: Thu, 31 Jul 2014 00:52:27 +0900 (JST)
Subject: [ruby-changes:34926] nagachika:r47009 (ruby_2_1): merge revision(s) r46419, r46429: [Backport #9940]
nagachika 2014-07-31 00:52:15 +0900 (Thu, 31 Jul 2014) New Revision: 47009 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47009 Log: merge revision(s) r46419,r46429: [Backport #9940] * vm_trace.c: clear and restore recursive checking thread local data to avoid unexpected throw from TracePoint. [Bug #9940] * test/ruby/test_settracefunc.rb: add a test. * thread.c: adde * rb_threadptr_reset_recursive_data(rb_thread_t *th); * rb_threadptr_restore_recursive_data(rb_thread_t *th, VALUE old); * vm_core.h: ditto. * thread.c: added Modified directories: branches/ruby_2_1/ Modified files: branches/ruby_2_1/ChangeLog branches/ruby_2_1/test/ruby/test_settracefunc.rb branches/ruby_2_1/thread.c branches/ruby_2_1/version.h branches/ruby_2_1/vm_core.h branches/ruby_2_1/vm_trace.c Index: ruby_2_1/ChangeLog =================================================================== --- ruby_2_1/ChangeLog (revision 47008) +++ ruby_2_1/ChangeLog (revision 47009) @@ -1,3 +1,17 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ChangeLog#L1 +Thu Jul 31 00:44:34 2014 Koichi Sasada <ko1@a...> + + * vm_trace.c: clear and restore recursive checking thread local data + to avoid unexpected throw from TracePoint. + [Bug #9940] + + * test/ruby/test_settracefunc.rb: add a test. + + * thread.c: added + * rb_threadptr_reset_recursive_data(rb_thread_t *th); + * rb_threadptr_restore_recursive_data(rb_thread_t *th, VALUE old); + + * vm_core.h: ditto. + Wed Jul 23 23:49:59 2014 Hiroshi Shirosaki <h.shirosaki@g...> * lib/test/unit/parallel.rb: fix test-all parallel failure if a test Index: ruby_2_1/vm_core.h =================================================================== --- ruby_2_1/vm_core.h (revision 47008) +++ ruby_2_1/vm_core.h (revision 47009) @@ -1032,6 +1032,9 @@ void rb_threadptr_exec_event_hooks_and_p https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm_core.h#L1032 #define EXEC_EVENT_HOOK_AND_POP_FRAME(th_, flag_, self_, id_, klass_, data_) \ EXEC_EVENT_HOOK_ORIG(th_, flag_, self_, id_, klass_, data_, 1) +VALUE rb_threadptr_reset_recursive_data(rb_thread_t *th); +void rb_threadptr_restore_recursive_data(rb_thread_t *th, VALUE old); + RUBY_SYMBOL_EXPORT_BEGIN int rb_thread_check_trap_pending(void); Index: ruby_2_1/thread.c =================================================================== --- ruby_2_1/thread.c (revision 47008) +++ ruby_2_1/thread.c (revision 47009) @@ -2746,22 +2746,25 @@ rb_thread_inspect(VALUE thread) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/thread.c#L2746 return str; } -VALUE -rb_thread_local_aref(VALUE thread, ID id) +static VALUE +threadptr_local_aref(rb_thread_t *th, ID id) { - rb_thread_t *th; st_data_t val; - GetThreadPtr(thread, th); - if (!th->local_storage) { - return Qnil; - } - if (st_lookup(th->local_storage, id, &val)) { + if (th->local_storage && st_lookup(th->local_storage, id, &val)) { return (VALUE)val; } return Qnil; } +VALUE +rb_thread_local_aref(VALUE thread, ID id) +{ + rb_thread_t *th; + GetThreadPtr(thread, th); + return threadptr_local_aref(th, id); +} + /* * call-seq: * thr[sym] -> obj or nil @@ -2830,26 +2833,35 @@ rb_thread_aref(VALUE thread, VALUE key) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/thread.c#L2833 return rb_thread_local_aref(thread, id); } -VALUE -rb_thread_local_aset(VALUE thread, ID id, VALUE val) +static VALUE +threadptr_local_aset(rb_thread_t *th, ID id, VALUE val) { - rb_thread_t *th; - GetThreadPtr(thread, th); - - if (OBJ_FROZEN(thread)) { - rb_error_frozen("thread locals"); - } if (NIL_P(val)) { if (!th->local_storage) return Qnil; st_delete_wrap(th->local_storage, id); return Qnil; } + else { if (!th->local_storage) { th->local_storage = st_init_numtable(); } st_insert(th->local_storage, id, val); return val; } +} + +VALUE +rb_thread_local_aset(VALUE thread, ID id, VALUE val) +{ + rb_thread_t *th; + GetThreadPtr(thread, th); + + if (OBJ_FROZEN(thread)) { + rb_error_frozen("thread locals"); + } + + return threadptr_local_aset(th, id, val); +} /* * call-seq: @@ -4778,6 +4790,20 @@ recursive_list_access(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_1/thread.c#L4790 return list; } +VALUE +rb_threadptr_reset_recursive_data(rb_thread_t *th) +{ + VALUE old = threadptr_local_aref(th, recursive_key); + threadptr_local_aset(th, recursive_key, Qnil); + return old; +} + +void +rb_threadptr_restore_recursive_data(rb_thread_t *th, VALUE old) +{ + threadptr_local_aset(th, recursive_key, old); +} + /* * Returns Qtrue iff obj_id (or the pair <obj, paired_obj>) is already * in the recursion list. Index: ruby_2_1/vm_trace.c =================================================================== --- ruby_2_1/vm_trace.c (revision 47008) +++ ruby_2_1/vm_trace.c (revision 47009) @@ -335,6 +335,7 @@ rb_threadptr_exec_event_hooks_orig(rb_tr https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm_trace.c#L335 trace_arg->self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) { const VALUE errinfo = th->errinfo; const int outer_state = th->state; + const VALUE old_recursive = rb_threadptr_reset_recursive_data(th); int state = 0; th->state = 0; th->errinfo = Qnil; @@ -355,6 +356,7 @@ rb_threadptr_exec_event_hooks_orig(rb_tr https://github.com/ruby/ruby/blob/trunk/ruby_2_1/vm_trace.c#L356 terminate: th->trace_arg = 0; th->vm->trace_running--; + rb_threadptr_restore_recursive_data(th, old_recursive); if (state) { if (pop_p) { Index: ruby_2_1/version.h =================================================================== --- ruby_2_1/version.h (revision 47008) +++ ruby_2_1/version.h (revision 47009) @@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/version.h#L1 #define RUBY_VERSION "2.1.2" -#define RUBY_RELEASE_DATE "2014-07-23" -#define RUBY_PATCHLEVEL 182 +#define RUBY_RELEASE_DATE "2014-07-31" +#define RUBY_PATCHLEVEL 183 #define RUBY_RELEASE_YEAR 2014 #define RUBY_RELEASE_MONTH 7 -#define RUBY_RELEASE_DAY 23 +#define RUBY_RELEASE_DAY 31 #include "ruby/version.h" Index: ruby_2_1/test/ruby/test_settracefunc.rb =================================================================== --- ruby_2_1/test/ruby/test_settracefunc.rb (revision 47008) +++ ruby_2_1/test/ruby/test_settracefunc.rb (revision 47009) @@ -1182,6 +1182,18 @@ class TestSetTraceFunc < Test::Unit::Tes https://github.com/ruby/ruby/blob/trunk/ruby_2_1/test/ruby/test_settracefunc.rb#L1182 assert_equal([['call', :foo], ['return', :foo]], events, 'Bug #9759') ensure end + end + def test_recursive + assert_ruby_status [], %q{ + stack = [] + TracePoint.new(:c_call){|tp| + p 2 + stack << tp.method_id + }.enable{ + p 1 + } + raise if stack != [:p, :hash, :inspect] + }, '[Bug #9940]' end end Property changes on: ruby_2_1 ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r46419,46429 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/