Skip to content

Commit 75a999b

Browse files
committed
merge revision(s) r46419,r46429: [Backport ruby#9940]
* vm_trace.c: clear and restore recursive checking thread local data to avoid unexpected throw from TracePoint. [Bug ruby#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 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@47009 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 15d2f7a commit 75a999b

File tree

6 files changed

+76
-19
lines changed

6 files changed

+76
-19
lines changed

ChangeLog

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
Thu Jul 31 00:44:34 2014 Koichi Sasada <[email protected]>
2+
3+
* vm_trace.c: clear and restore recursive checking thread local data
4+
to avoid unexpected throw from TracePoint.
5+
[Bug #9940]
6+
7+
* test/ruby/test_settracefunc.rb: add a test.
8+
9+
* thread.c: added
10+
* rb_threadptr_reset_recursive_data(rb_thread_t *th);
11+
* rb_threadptr_restore_recursive_data(rb_thread_t *th, VALUE old);
12+
13+
* vm_core.h: ditto.
14+
115
Wed Jul 23 23:49:59 2014 Hiroshi Shirosaki <[email protected]>
216

317
* lib/test/unit/parallel.rb: fix test-all parallel failure if a test

test/ruby/test_settracefunc.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,18 @@ def test_define_method_on_exception
11821182
assert_equal([['call', :foo], ['return', :foo]], events, 'Bug #9759')
11831183
ensure
11841184
end
1185+
end
11851186

1187+
def test_recursive
1188+
assert_ruby_status [], %q{
1189+
stack = []
1190+
TracePoint.new(:c_call){|tp|
1191+
p 2
1192+
stack << tp.method_id
1193+
}.enable{
1194+
p 1
1195+
}
1196+
raise if stack != [:p, :hash, :inspect]
1197+
}, '[Bug #9940]'
11861198
end
11871199
end

thread.c

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,22 +2746,25 @@ rb_thread_inspect(VALUE thread)
27462746
return str;
27472747
}
27482748

2749-
VALUE
2750-
rb_thread_local_aref(VALUE thread, ID id)
2749+
static VALUE
2750+
threadptr_local_aref(rb_thread_t *th, ID id)
27512751
{
2752-
rb_thread_t *th;
27532752
st_data_t val;
27542753

2755-
GetThreadPtr(thread, th);
2756-
if (!th->local_storage) {
2757-
return Qnil;
2758-
}
2759-
if (st_lookup(th->local_storage, id, &val)) {
2754+
if (th->local_storage && st_lookup(th->local_storage, id, &val)) {
27602755
return (VALUE)val;
27612756
}
27622757
return Qnil;
27632758
}
27642759

2760+
VALUE
2761+
rb_thread_local_aref(VALUE thread, ID id)
2762+
{
2763+
rb_thread_t *th;
2764+
GetThreadPtr(thread, th);
2765+
return threadptr_local_aref(th, id);
2766+
}
2767+
27652768
/*
27662769
* call-seq:
27672770
* thr[sym] -> obj or nil
@@ -2830,26 +2833,35 @@ rb_thread_aref(VALUE thread, VALUE key)
28302833
return rb_thread_local_aref(thread, id);
28312834
}
28322835

2833-
VALUE
2834-
rb_thread_local_aset(VALUE thread, ID id, VALUE val)
2836+
static VALUE
2837+
threadptr_local_aset(rb_thread_t *th, ID id, VALUE val)
28352838
{
2836-
rb_thread_t *th;
2837-
GetThreadPtr(thread, th);
2838-
2839-
if (OBJ_FROZEN(thread)) {
2840-
rb_error_frozen("thread locals");
2841-
}
28422839
if (NIL_P(val)) {
28432840
if (!th->local_storage) return Qnil;
28442841
st_delete_wrap(th->local_storage, id);
28452842
return Qnil;
28462843
}
2844+
else {
28472845
if (!th->local_storage) {
28482846
th->local_storage = st_init_numtable();
28492847
}
28502848
st_insert(th->local_storage, id, val);
28512849
return val;
28522850
}
2851+
}
2852+
2853+
VALUE
2854+
rb_thread_local_aset(VALUE thread, ID id, VALUE val)
2855+
{
2856+
rb_thread_t *th;
2857+
GetThreadPtr(thread, th);
2858+
2859+
if (OBJ_FROZEN(thread)) {
2860+
rb_error_frozen("thread locals");
2861+
}
2862+
2863+
return threadptr_local_aset(th, id, val);
2864+
}
28532865

28542866
/*
28552867
* call-seq:
@@ -4778,6 +4790,20 @@ recursive_list_access(void)
47784790
return list;
47794791
}
47804792

4793+
VALUE
4794+
rb_threadptr_reset_recursive_data(rb_thread_t *th)
4795+
{
4796+
VALUE old = threadptr_local_aref(th, recursive_key);
4797+
threadptr_local_aset(th, recursive_key, Qnil);
4798+
return old;
4799+
}
4800+
4801+
void
4802+
rb_threadptr_restore_recursive_data(rb_thread_t *th, VALUE old)
4803+
{
4804+
threadptr_local_aset(th, recursive_key, old);
4805+
}
4806+
47814807
/*
47824808
* Returns Qtrue iff obj_id (or the pair <obj, paired_obj>) is already
47834809
* in the recursion list.

version.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#define RUBY_VERSION "2.1.2"
2-
#define RUBY_RELEASE_DATE "2014-07-23"
3-
#define RUBY_PATCHLEVEL 182
2+
#define RUBY_RELEASE_DATE "2014-07-31"
3+
#define RUBY_PATCHLEVEL 183
44

55
#define RUBY_RELEASE_YEAR 2014
66
#define RUBY_RELEASE_MONTH 7
7-
#define RUBY_RELEASE_DAY 23
7+
#define RUBY_RELEASE_DAY 31
88

99
#include "ruby/version.h"
1010

vm_core.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,9 @@ void rb_threadptr_exec_event_hooks_and_pop_frame(struct rb_trace_arg_struct *tra
10321032
#define EXEC_EVENT_HOOK_AND_POP_FRAME(th_, flag_, self_, id_, klass_, data_) \
10331033
EXEC_EVENT_HOOK_ORIG(th_, flag_, self_, id_, klass_, data_, 1)
10341034

1035+
VALUE rb_threadptr_reset_recursive_data(rb_thread_t *th);
1036+
void rb_threadptr_restore_recursive_data(rb_thread_t *th, VALUE old);
1037+
10351038
RUBY_SYMBOL_EXPORT_BEGIN
10361039

10371040
int rb_thread_check_trap_pending(void);

vm_trace.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
335335
trace_arg->self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) {
336336
const VALUE errinfo = th->errinfo;
337337
const int outer_state = th->state;
338+
const VALUE old_recursive = rb_threadptr_reset_recursive_data(th);
338339
int state = 0;
339340
th->state = 0;
340341
th->errinfo = Qnil;
@@ -355,6 +356,7 @@ rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
355356
terminate:
356357
th->trace_arg = 0;
357358
th->vm->trace_running--;
359+
rb_threadptr_restore_recursive_data(th, old_recursive);
358360

359361
if (state) {
360362
if (pop_p) {

0 commit comments

Comments
 (0)