1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* proc.c (rb_binding_new_with_cfp): permit to create binding object

of IFUNC frame.
  When `rb_binding_new_with_cfp()' is called, VM finds out the first
  normal (has iseq) frame and create a binding object of this frame
  and create Env objects. `ep's of related frames are updated
  (`ep's point Env object managed spaces).
  However, `ep' of skipped IFUNC frame was not updated and
  old invalid `ep' was remained. It causes serious problems.
  To solve this issue, permit IFUNC to create binding.
  (Maybe there is no problem on it)
  [ruby-dev:46908] [ruby-trunk - Bug #7774]
* test/ruby/test_settracefunc.rb: add a test.
* vm.c (rb_vm_get_binding_creatable_next_cfp), vm_core.h: added.
* vm_trace.c: fix to use `rb_vm_get_binding_creatable_next_cfp()'.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39067 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2013-02-05 06:04:59 +00:00
parent 757bbe8737
commit 88101695ab
6 changed files with 59 additions and 5 deletions

View file

@ -1,3 +1,23 @@
Tue Feb 05 15:04:34 2013 Koichi Sasada <ko1@atdot.net>
* proc.c (rb_binding_new_with_cfp): permit to create binding object
of IFUNC frame.
When `rb_binding_new_with_cfp()' is called, VM finds out the first
normal (has iseq) frame and create a binding object of this frame
and create Env objects. `ep's of related frames are updated
(`ep's point Env object managed spaces).
However, `ep' of skipped IFUNC frame was not updated and
old invalid `ep' was remained. It causes serious problems.
To solve this issue, permit IFUNC to create binding.
(Maybe there is no problem on it)
[ruby-dev:46908] [ruby-trunk - Bug #7774]
* test/ruby/test_settracefunc.rb: add a test.
* vm.c (rb_vm_get_binding_creatable_next_cfp), vm_core.h: added.
* vm_trace.c: fix to use `rb_vm_get_binding_creatable_next_cfp()'.
Tue Feb 5 14:43:15 2013 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
* lib/matrix.rb: Fix error message, patch by pypypy [Bug #7777]

10
proc.c
View file

@ -313,19 +313,21 @@ binding_clone(VALUE self)
VALUE
rb_binding_new_with_cfp(rb_thread_t *th, const rb_control_frame_t *src_cfp)
{
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp);
rb_control_frame_t *cfp = rb_vm_get_binding_creatable_next_cfp(th, src_cfp);
rb_control_frame_t *ruby_level_cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp);
VALUE bindval;
rb_binding_t *bind;
if (cfp == 0) {
if (cfp == 0 || ruby_level_cfp == 0) {
rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
}
bindval = binding_alloc(rb_cBinding);
GetBindingPtr(bindval, bind);
bind->env = rb_vm_make_env_object(th, cfp);
bind->path = cfp->iseq->location.path;
bind->first_lineno = rb_vm_get_sourceline(cfp);
bind->path = ruby_level_cfp->iseq->location.path;
bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp);
return bindval;
}

View file

@ -941,4 +941,22 @@ class TestSetTraceFunc < Test::Unit::TestCase
end
assert_security_error_safe4(func)
end
def test_trace_point_binding_in_ifunc
assert_normal_exit %q{
tp = TracePoint.new(:raise) do |tp|
tp.binding
end
tp.enable do
obj = Object.new
class << obj
include Enumerable
def each
yield 1
end
end
obj.zip({}) {}
end
}, '[ruby-dev:46908] [ruby-trunk - Bug #7774]'
end
end

12
vm.c
View file

@ -185,6 +185,18 @@ vm_set_main_stack(rb_thread_t *th, VALUE iseqval)
}
}
rb_control_frame_t *
rb_vm_get_binding_creatable_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp)
{
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
if (cfp->iseq) {
return (rb_control_frame_t *)cfp;
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
return 0;
}
rb_control_frame_t *
rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp)
{

View file

@ -843,6 +843,7 @@ void rb_thread_wakeup_timer_thread(void);
int ruby_thread_has_gvl_p(void);
typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE);
rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp);
rb_control_frame_t *rb_vm_get_binding_creatable_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp);
int rb_vm_get_sourceline(const rb_control_frame_t *);
VALUE rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method);
void rb_vm_stack_to_heap(rb_thread_t *th);

View file

@ -763,7 +763,8 @@ VALUE
rb_tracearg_binding(rb_trace_arg_t *trace_arg)
{
rb_control_frame_t *cfp;
cfp = rb_vm_get_ruby_level_next_cfp(trace_arg->th, trace_arg->cfp);
cfp = rb_vm_get_binding_creatable_next_cfp(trace_arg->th, trace_arg->cfp);
if (cfp) {
return rb_binding_new_with_cfp(trace_arg->th, cfp);
}