summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-09-21 06:41:07 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-09-21 06:41:07 +0000
commitac4b2d990c8484af7a214381e61d3494b6b858b1 (patch)
tree772448ed64eb627f8c03f37f4a5eaca95a29aecd
parenta810a1a78c6ed91debffc37d9f8e6bea07decbcf (diff)
escape all env properly.
* vm_backtrace.c (rb_debug_inspector_open): escape all env using `rb_vm_stack_to_heap()` before making bindings. [Bug #15105] There is a complicated story of this issue: Without this patch, IFUNC frame does not escaped. A IFUNC frame points to CFUNC ep as previous ep. However, CFUNC ep can be escaped because of making bindings of Ruby level frames. IFUNC's ep can points to invalidated ep and `rb_iter_break()` will fail. This is why `any?` fails. * test/-ext-/debug/test_debug.rb: add a test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64800 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--test/-ext-/debug/test_debug.rb16
-rw-r--r--vm_backtrace.c3
2 files changed, 19 insertions, 0 deletions
diff --git a/test/-ext-/debug/test_debug.rb b/test/-ext-/debug/test_debug.rb
index 3804714..da66b1b 100644
--- a/test/-ext-/debug/test_debug.rb
+++ b/test/-ext-/debug/test_debug.rb
@@ -56,4 +56,20 @@ class TestDebug < Test::Unit::TestCase
binds = inspector_in_eval
binds_check binds, bug7635
end
+
+ class MyRelation
+ include Enumerable
+
+ def each
+ yield :each_entry
+ end
+ end
+
+ def test_lazy_block
+ x = MyRelation.new.any? do
+ Bug::Debug.inspector
+ true
+ end
+ assert_equal true, x, '[Bug #15105]'
+ end
end
diff --git a/vm_backtrace.c b/vm_backtrace.c
index 5934029..0493ed8 100644
--- a/vm_backtrace.c
+++ b/vm_backtrace.c
@@ -1202,6 +1202,9 @@ rb_debug_inspector_open(rb_debug_inspector_func_t func, void *data)
enum ruby_tag_type state;
volatile VALUE MAYBE_UNUSED(result);
+ /* escape all env to heap */
+ rb_vm_stack_to_heap(ec);
+
dbg_context.ec = ec;
dbg_context.cfp = dbg_context.ec->cfp;
dbg_context.backtrace = ec_backtrace_location_ary(ec, 0, 0);