[ruby-dev:48299] [ruby-trunk - Bug #9961] [Open] TracePoint can skip c_return with rb_rescue()

From: ko1@...
Date: 2014-06-19 12:40:54 UTC
List: ruby-dev #48299
Issue #9961 has been reported by Koichi Sasada.

----------------------------------------
Bug #9961: TracePoint can skip c_return with rb_rescue()
https://bugs.ruby-lang.org/issues/9961

* Author: Koichi Sasada
* Status: Open
* Priority: Normal
* Assignee: Koichi Sasada
* Category: core
* Target version: current: 2.2.0
* ruby -v: 2.2
* Backport: 2.0.0: REQUIRED, 2.1: REQUIRED
----------------------------------------
=E4=B8=8B=E8=A8=98=E3=81=AE=E3=82=88=E3=81=86=E3=81=AA=E3=83=86=E3=82=B9=E3=
=83=88=E3=81=AB=E5=A4=B1=E6=95=97=E3=81=97=E3=81=BE=E3=81=99=E3=80=82

```ruby
  def test_rb_rescue
    events =3D []
    curr_thread =3D Thread.current
    TracePoint.new(:a_call, :a_return){|tp|
      next if curr_thread !=3D Thread.current
      events << [tp.event, tp.method_id]
    }.enable do
      begin
        -Numeric.new
      rescue =3D> e
        # ignore
      end
    end

    assert_equal [
    [:b_call, :test_rb_rescue],
      [:c_call, :new],
        [:c_call, :initialize],
        [:c_return, :initialize],
      [:c_return, :new],
      [:c_call, :-@],
        [:c_call, :coerce],
          [:c_call, :to_s],
          [:c_return, :to_s],
          [:c_call, :new],
            [:c_call, :initialize],
            [:c_return, :initialize],
          [:c_return, :new],
          [:c_call, :exception],
          [:c_return, :exception],
          [:c_call, :backtrace],
          [:c_return, :backtrace],
        [:c_return, :coerce],            # don't miss it!
        [:c_call, :to_s],
        [:c_return, :to_s],
        [:c_call, :to_s],
        [:c_return, :to_s],
        [:c_call, :new],
          [:c_call, :initialize],
          [:c_return, :initialize],
        [:c_return, :new],
        [:c_call, :exception],
        [:c_return, :exception],
        [:c_call, :backtrace],
        [:c_return, :backtrace],
      [:c_return, :-@],
      [:c_call, :=3D=3D=3D],
      [:c_return, :=3D=3D=3D],
    [:b_return, :test_rb_rescue]], events
  end
```

=E4=BD=95=E3=81=8C=E8=B5=B7=E3=81=8D=E3=81=A6=E3=81=84=E3=82=8B=E3=81=8B=E3=
=81=A8=E3=81=84=E3=81=86=E3=81=A8=E3=80=81

(1) -Numeric.new =E3=81=A7 rb_rescue() =E3=81=AE=E5=BE=8C=E3=81=A7 rb_funca=
ll() =E3=81=97=E3=81=9F=E5=85=88=E3=81=A7=E4=BE=8B=E5=A4=96=E3=81=8C=E8=B5=
=B7=E3=81=93=E3=82=8B
(2) rb_rescue() =E3=81=A7=E3=81=AF=E3=80=81c_return =E3=82=92=E7=84=A1=E8=
=A6=96=E3=81=97=E3=81=A6 cfp =E3=82=92=E5=88=87=E3=82=8A=E8=A9=B0=E3=82=81=
=E3=82=8B

=E3=81=A8=E3=81=84=E3=81=86=E3=81=93=E3=81=A8=E3=81=AB=E3=82=88=E3=82=8A=E3=
=80=81c_return =E3=81=8C=E3=82=B9=E3=82=AD=E3=83=83=E3=83=97=E3=81=97=E3=81=
=A6=E3=81=97=E3=81=BE=E3=81=86=E3=80=81=E3=81=A8=E3=81=84=E3=81=86=E7=8F=BE=
=E8=B1=A1=E3=81=A8=E3=81=AA=E3=82=8A=E3=81=BE=E3=81=97=E3=81=9F=E3=80=82

=E6=AC=A1=E3=81=AE=E3=83=91=E3=83=83=E3=83=81=E3=81=A7=E8=A7=A3=E6=B1=BA=E3=
=81=97=E3=81=BE=E3=81=99=E3=80=82

```diff
Index: eval.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- eval.c	(revision 46464)
+++ eval.c	(working copy)
@@ -803,7 +803,7 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), V
 	}
     }
     else {
-	th->cfp =3D cfp; /* restore */
+	rb_vm_rewind_cfp(th, cfp);
=20
 	if (state =3D=3D TAG_RAISE) {
 	    int handle =3D FALSE;
@@ -862,7 +862,7 @@ rb_protect(VALUE (* proc) (VALUE), VALUE
 	SAVE_ROOT_JMPBUF(th, result =3D (*proc) (data));
     }
     else {
-	th->cfp =3D cfp;
+	rb_vm_rewind_cfp(th, cfp);
     }
     MEMCPY(&(th)->root_jmpbuf, &org_jmpbuf, rb_jmpbuf_t, 1);
     th->protect_tag =3D protect_tag.prev;
Index: vm.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- vm.c	(revision 46464)
+++ vm.c	(working copy)
@@ -288,6 +288,23 @@ rb_vm_pop_cfunc_frame(void)
     vm_pop_frame(th);
 }
=20
+void
+rb_vm_rewind_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
+{
+    /* check skipped frame */
+    while (th->cfp !=3D cfp) {
+#if VMDEBUG
+	printf("skipped frame: %s\n", vm_frametype_name(th->cfp));
+#endif
+	if (VM_FRAME_TYPE(th->cfp) !=3D VM_FRAME_MAGIC_CFUNC) {
+	    vm_pop_frame(th);
+	}
+	else { /* unlikely path */
+	    rb_vm_pop_cfunc_frame();
+	}
+    }
+}
+
 /* obsolete */
 void
 rb_frame_pop(void)
Index: vm_core.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- vm_core.h	(revision 46464)
+++ vm_core.h	(working copy)
@@ -901,6 +901,7 @@ VALUE rb_name_err_mesg_new(VALUE obj, VA
 void rb_vm_stack_to_heap(rb_thread_t *th);
 void ruby_thread_init_stack(rb_thread_t *th);
 int rb_vm_control_frame_id_and_class(const rb_control_frame_t *cfp, ID *id=
p, VALUE *klassp);
+void rb_vm_rewind_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
=20
 void rb_gc_mark_machine_stack(rb_thread_t *th);
=20
Index: vm_eval.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- vm_eval.c	(revision 46464)
+++ vm_eval.c	(working copy)
@@ -1093,18 +1093,7 @@ rb_iterate(VALUE (* it_proc) (VALUE), VA
 		th->errinfo =3D Qnil;
 		retval =3D GET_THROWOBJ_VAL(err);
=20
-		/* check skipped frame */
-		while (th->cfp !=3D cfp) {
-#if VMDEBUG
-		    printf("skipped frame: %s\n", vm_frametype_name(th->cfp));
-#endif
-		    if (VM_FRAME_TYPE(th->cfp) !=3D VM_FRAME_MAGIC_CFUNC) {
-			vm_pop_frame(th);
-		    }
-		    else { /* unlikely path */
-			rb_vm_pop_cfunc_frame();
-		    }
-		}
+		rb_vm_rewind_cfp(th, cfp);
 	    }
 	    else{
 		/* SDR(); printf("%p, %p\n", cdfp, escape_dfp); */
```

=E4=BE=8B=E3=81=AB=E3=82=88=E3=81=A3=E3=81=A6=E3=80=812.1, 2.0 =E3=81=A7=E3=
=82=82=E3=81=8A=E3=81=8D=E3=81=BE=E3=81=99=E3=80=82

=EF=BC=88Numeric.new =E3=81=AA=E3=82=93=E3=81=A6=E3=81=A7=E3=81=8D=E3=82=8B=
=E3=81=A8=E3=81=AF=E7=9F=A5=E3=82=89=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F=EF=
=BC=89




--=20
https://bugs.ruby-lang.org/

In This Thread

Prev Next