From 428791543be9e13af9426970f5796f3157dd30a0 Mon Sep 17 00:00:00 2001 From: nobu Date: Tue, 9 Dec 2014 01:16:27 +0000 Subject: [PATCH] thread.c: get rid of invalid ID symbol * eval.c (rb_frame_last_func): return the most recent frame method name. * thread.c (recursive_list_access): use the last method name, instead of the current method name which can be unset in some cases, not to use a symbol by the invalid ID. [ruby-core:66742] [Bug #10579] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48744 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 ++++++++++ eval.c | 13 +++++++++++++ test/ruby/test_objectspace.rb | 7 +++++++ thread.c | 5 ++++- 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 50520e4976..74fa222989 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Tue Dec 9 10:16:24 2014 Nobuyoshi Nakada + + * eval.c (rb_frame_last_func): return the most recent frame method + name. + + * thread.c (recursive_list_access): use the last method name, + instead of the current method name which can be unset in some + cases, not to use a symbol by the invalid ID. + [ruby-core:66742] [Bug #10579] + Sun Dec 7 19:36:12 2014 Kazuki Tsujimoto * ext/socket/basicsocket.c, ext/socket/sockssocket.c: diff --git a/eval.c b/eval.c index 8390c7dc31..dc5af43928 100644 --- a/eval.c +++ b/eval.c @@ -1030,6 +1030,19 @@ prev_frame_func(void) return frame_func_id(prev_cfp); } +ID +rb_frame_last_func(void) +{ + rb_thread_t *th = GET_THREAD(); + rb_control_frame_t *cfp = th->cfp; + ID mid; + + while (!(mid = frame_func_id(cfp)) && + (cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp), + !RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp))); + return mid; +} + /* * call-seq: * append_features(mod) -> mod diff --git a/test/ruby/test_objectspace.rb b/test/ruby/test_objectspace.rb index 4b8ae74a3c..d519041f0b 100644 --- a/test/ruby/test_objectspace.rb +++ b/test/ruby/test_objectspace.rb @@ -102,4 +102,11 @@ End } End end + + def test_each_object_recursive_key + assert_normal_exit(<<-'end;', '[ruby-core:66742] [Bug #10579]') + h = {["foo"]=>nil} + p Thread.current[:__recursive_key__] + end; + end end diff --git a/thread.c b/thread.c index 25cc2143e9..360c6cb6b9 100644 --- a/thread.c +++ b/thread.c @@ -4696,6 +4696,8 @@ threadptr_recursive_hash_set(rb_thread_t *th, VALUE hash) th->local_storage_recursive_hash = hash; } +ID rb_frame_last_func(void); + /* * Returns the current "recursive list" used to detect recursion. * This list is a hash table, unique for the current thread and for @@ -4707,7 +4709,8 @@ recursive_list_access(void) { rb_thread_t *th = GET_THREAD(); VALUE hash = threadptr_recursive_hash(th); - VALUE sym = ID2SYM(rb_frame_this_func()); + ID mid = rb_frame_last_func(); + VALUE sym = mid ? ID2SYM(mid) : ID2SYM(idNULL); VALUE list; if (NIL_P(hash) || !RB_TYPE_P(hash, T_HASH)) { hash = ident_hash_new();